今度もオンライン上だけでの参加になりました。
ネタのリサイクルになりますが、Qiitaに投稿したものをブログにも投下しときます。
C++で、その1
#include <sstream> #include <iostream> #include <iomanip> #include <vector> typedef std::vector<unsigned int> Field; struct Data { const char* input; const char* output; }; const Data data[] = { /* 0*/ { "ff-2f-23-f3-77-7f-3b", "1f-03-00-1c-0d-0f-06" }, /* 1*/ { "01", "00" }, /* 2*/ { "00", "00" }, /* 3*/ { "7a-4e", "0c-02" }, /* 4*/ { "56-b6", "08-14" }, /* 5*/ { "12-12-12", "00-00-00" }, /* 6*/ { "de-ff-7b", "0a-0f-05" }, /* 7*/ { "95-be-d0", "05-1e-20" }, /* 8*/ { "7c-b0-bb", "1c-20-2b" }, /* 9*/ { "7a-b6-31-6a", "3a-56-11-2a" }, /*10*/ { "32-0e-23-82", "18-06-11-40" }, /*11*/ { "ff-7f-bf-df-ef", "0f-07-0b-0d-0e" }, /*12*/ { "75-df-dc-6e-42", "35-5f-5c-2e-02" }, /*13*/ { "62-51-ef-c7-f8", "22-11-6f-47-78" }, /*14*/ { "0c-47-8e-dd-5d-17", "04-23-46-6d-2d-0b" }, /*15*/ { "aa-58-5b-6d-9f-1f", "52-28-2b-35-4f-0f" }, /*16*/ { "ff-55-d5-75-5d-57", "0f-00-08-04-02-01" }, /*17*/ { "fe-fd-fb-f7-ef-df-bf", "7e-7d-7b-77-6f-5f-3f" }, /*18*/ { "fd-fb-f7-ef-df-bf-7f", "7e-7d-7b-77-6f-5f-3f" }, /*19*/ { "d9-15-b5-d7-1b-9f-de", "69-05-55-67-0b-4f-6e" }, /*20*/ { "38-15-fd-50-10-96-ba", "18-05-7d-20-00-46-5a" }, /*21*/ { "fe-fd-fb-f7-ef-df-bf-7f", "fe-fd-fb-f7-ef-df-bf-7f" }, { 0, 0 } }; std::istream& operator >> (std::istream& in, Field& field) { in >> std::hex; unsigned int n; do { in >> n; field.push_back(n); char c; in >> c; } while(in.good()); return in; } std::ostream& operator << (std::ostream& out, const Field& field) { int fill = out.fill('0'); out << std::hex; Field::const_iterator i = field.begin(); out << std::setw(2) << *i++; for(; i != field.end(); ++i) { out << "-" << std::setw(2) << *i; } out << std::dec; out.fill(fill); return out; } int main(int, char* []) { for(const Data* d = data; d->input != 0; ++d) { Field field; std::istringstream iss(d->input); iss >> field; Field::iterator i = field.begin(); Field::value_type v = *i++; for(; i != field.end(); ++i) { v &= *i; } for(int i = 7; i >= 0; --i) { if(((v >> i) & 1) != 0) { for(Field::iterator f = field.begin(); f != field.end(); ++f) { *f = (*f & (0xffu >> (8 - i))) | ((*f >> 1) & (0xffu << i)); } } } std::ostringstream oss; oss << field; std::string result = oss.str(); std::cout << result << " : " << ((result == d->output) ? "PASSED" : "FAILED") << std::endl; } return 0; }
C++で、その2
ラムダ関数が使いたかったのでC++11で書いてます。
#include <sstream> #include <iostream> #include <iomanip> #include <vector> #include <algorithm> #include <numeric> typedef std::vector<unsigned int> Field; struct Data { const char* input; const char* output; }; const Data data[] = { /* 0*/ { "ff-2f-23-f3-77-7f-3b", "1f-03-00-1c-0d-0f-06" }, /* 1*/ { "01", "00" }, /* 2*/ { "00", "00" }, /* 3*/ { "7a-4e", "0c-02" }, /* 4*/ { "56-b6", "08-14" }, /* 5*/ { "12-12-12", "00-00-00" }, /* 6*/ { "de-ff-7b", "0a-0f-05" }, /* 7*/ { "95-be-d0", "05-1e-20" }, /* 8*/ { "7c-b0-bb", "1c-20-2b" }, /* 9*/ { "7a-b6-31-6a", "3a-56-11-2a" }, /*10*/ { "32-0e-23-82", "18-06-11-40" }, /*11*/ { "ff-7f-bf-df-ef", "0f-07-0b-0d-0e" }, /*12*/ { "75-df-dc-6e-42", "35-5f-5c-2e-02" }, /*13*/ { "62-51-ef-c7-f8", "22-11-6f-47-78" }, /*14*/ { "0c-47-8e-dd-5d-17", "04-23-46-6d-2d-0b" }, /*15*/ { "aa-58-5b-6d-9f-1f", "52-28-2b-35-4f-0f" }, /*16*/ { "ff-55-d5-75-5d-57", "0f-00-08-04-02-01" }, /*17*/ { "fe-fd-fb-f7-ef-df-bf", "7e-7d-7b-77-6f-5f-3f" }, /*18*/ { "fd-fb-f7-ef-df-bf-7f", "7e-7d-7b-77-6f-5f-3f" }, /*19*/ { "d9-15-b5-d7-1b-9f-de", "69-05-55-67-0b-4f-6e" }, /*20*/ { "38-15-fd-50-10-96-ba", "18-05-7d-20-00-46-5a" }, /*21*/ { "fe-fd-fb-f7-ef-df-bf-7f", "fe-fd-fb-f7-ef-df-bf-7f" }, { 0, 0 } }; std::istream& operator >> (std::istream& in, Field& field) { in >> std::hex; unsigned int n; do { in >> n; field.push_back(n); char c; in >> c; } while(in.good()); return in; } std::ostream& operator << (std::ostream& out, const Field& field) { int fill = out.fill('0'); out << std::hex; Field::const_iterator i = field.begin(); out << std::setw(2) << *i++; for(; i != field.end(); ++i) { out << "-" << std::setw(2) << *i; } out << std::dec; out.fill(fill); return out; } int main(int, char* []) { for(const Data* d = data; d->input != 0; ++d) { Field field; std::istringstream iss(d->input); iss >> field; Field::value_type v = std::accumulate(field.begin(), field.end(), 0xffu, [](unsigned int lhs, unsigned int rhs) { return lhs & rhs; }); for(int i = 7; i >= 0; --i) { if(((v >> i) & 1) != 0) { std::for_each(field.begin(), field.end(), [i](unsigned int& f) { f = (f & (0xffu >> (8 - i))) | ((f >> 1) & (0xffu << i)); }); } } std::ostringstream oss; oss << field; std::string result = oss.str(); std::cout << result << " : " << ((result == d->output) ? "PASSED" : "FAILED") << std::endl; } return 0; }
Javaで
すっ…ごい久々にJavaのコードを書きました。書き方が時代遅れになってないかが心配です。
class Tetris { static String[][] data = { /* 0*/ { "ff-2f-23-f3-77-7f-3b", "1f-03-00-1c-0d-0f-06" }, /* 1*/ { "01", "00" }, /* 2*/ { "00", "00" }, /* 3*/ { "7a-4e", "0c-02" }, /* 4*/ { "56-b6", "08-14" }, /* 5*/ { "12-12-12", "00-00-00" }, /* 6*/ { "de-ff-7b", "0a-0f-05" }, /* 7*/ { "95-be-d0", "05-1e-20" }, /* 8*/ { "7c-b0-bb", "1c-20-2b" }, /* 9*/ { "7a-b6-31-6a", "3a-56-11-2a" }, /*10*/ { "32-0e-23-82", "18-06-11-40" }, /*11*/ { "ff-7f-bf-df-ef", "0f-07-0b-0d-0e" }, /*12*/ { "75-df-dc-6e-42", "35-5f-5c-2e-02" }, /*13*/ { "62-51-ef-c7-f8", "22-11-6f-47-78" }, /*14*/ { "0c-47-8e-dd-5d-17", "04-23-46-6d-2d-0b" }, /*15*/ { "aa-58-5b-6d-9f-1f", "52-28-2b-35-4f-0f" }, /*16*/ { "ff-55-d5-75-5d-57", "0f-00-08-04-02-01" }, /*17*/ { "fe-fd-fb-f7-ef-df-bf", "7e-7d-7b-77-6f-5f-3f" }, /*18*/ { "fd-fb-f7-ef-df-bf-7f", "7e-7d-7b-77-6f-5f-3f" }, /*19*/ { "d9-15-b5-d7-1b-9f-de", "69-05-55-67-0b-4f-6e" }, /*20*/ { "38-15-fd-50-10-96-ba", "18-05-7d-20-00-46-5a" }, /*21*/ { "fe-fd-fb-f7-ef-df-bf-7f", "fe-fd-fb-f7-ef-df-bf-7f" } }; static String deleteLine(String[] in) { int[] field = new int[in.length]; int r = 0xff; for(int i = 0; i < in.length; ++i) { field[i] = Integer.valueOf(in[i], 16); r &= field[i]; } for(int i = 7; i >= 0; --i) { if(((r >> i) & 1) != 0) { for(int j = 0; j < field.length; ++j) { field[j] = (field[j] & (0xff >> (8 - i))) | ((field[j] >> 1) & (0xff << i)); } } } String result = String.format("%02x", field[0]); for(int i = 1; i < field.length; ++i) { result += String.format("-%02x", field[i]); } return result; } public static void main(String[] args) { for(String[] pair: data) { String result = deleteLine(pair[0].split("-")); System.out.println(result + " : " + (result.equals(pair[1]) ? "PASSED" : "FAILED")); } } }
Haskellで
module Main where import Data.Bits import Data.ByteString.Char8(pack, unpack, split) import Numeric(readHex, showHex) field :: String -> [Int] field = (map (fst.head.readHex.unpack)).(split '-').pack tetris s = foldr1 (++) $ map (flip showHex "-") $ map (deleteLine 0 v) $ f where f = field s v = foldr1 (.&.) f deleteLine i v d | v == 0 = d | v `mod` 2 /= 0 = deleteLine i (shift v (-1)) ((d .&. (shift 255 (i - 8))) .|. ((shift d (-1)) .&. (shift 255 i))) | otherwise = deleteLine (i + 1) (shift v (-1)) d main = getContents >>= putStrLn.unlines.(map tetris).lines
出力がヘロヘロです。力つきました…。
$ cat tetris.dat ff-2f-23-f3-77-7f-3b 01 00 7a-4e 56-b6 12-12-12 de-ff-7b 95-be-d0 7c-b0-bb 7a-b6-31-6a 32-0e-23-82 ff-7f-bf-df-ef 75-df-dc-6e-42 62-51-ef-c7-f8 0c-47-8e-dd-5d-17 aa-58-5b-6d-9f-1f ff-55-d5-75-5d-57 fe-fd-fb-f7-ef-df-bf fd-fb-f7-ef-df-bf-7f d9-15-b5-d7-1b-9f-de 38-15-fd-50-10-96-ba fe-fd-fb-f7-ef-df-bf-7f $ ./tetris < tetris.dat 1f-3-0-1c-d-f-6- 0- 0- c-2- 8-14- 0-0-0- a-f-5- 5-1e-20- 1c-20-2b- 3a-56-11-2a- 18-6-11-40- f-7-b-d-e- 35-5f-5c-2e-2- 22-11-6f-47-78- 4-23-46-6d-2d-b- 52-28-2b-35-4f-f- f-0-8-4-2-1- 7e-7d-7b-77-6f-5f-3f- 7e-7d-7b-77-6f-5f-3f- 69-5-55-67-b-4f-6e- 18-5-7d-20-0-46-5a- fe-fd-fb-f7-ef-df-bf-7f-