-
Notifications
You must be signed in to change notification settings - Fork 0
/
manchester-encode-a-data-stream.php
146 lines (118 loc) · 5.41 KB
/
manchester-encode-a-data-stream.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
/**
* Code Golf: Manchester encode a data stream
*
* @link https://codegolf.stackexchange.com/questions/2040/manchester-encode-a-data-stream
*/
// The code-golf framework includes the testing frameworks and handles the command line
require __DIR__.'/a/CodeGolfFramework.php';
/**
* Class ManchesterEncodeADataStream - the problem at hand
*/
class ManchesterEncodeADataStream extends ACodeGolfProblem
{
/////////////////////////////////////////////////////////////////////////
// The public interface
//
public function runTests()
{
$this->testCase([0x10, 0x02], [0xAA, 0xA9, 0xA6, 0xAA]);
$this->testCase([0xFF, 0x00, 0xAA, 0x55], [0x55, 0x55, 0xAA, 0xAA, 0x66, 0x66, 0x99, 0x99]);
$this->testCase([0x12, 0x34, 0x56, 0x78, 0x90], [0xA6, 0xA9, 0x9A, 0xA5, 0x96, 0x99, 0x6A, 0x95, 0xAA, 0x69]);
$this->testCase([0x01, 0x02, 0x03, 0xF1, 0xF2, 0xF3], [0xA9, 0xAA, 0xA6, 0xAA, 0xA5, 0xAA, 0xA9, 0x55, 0xA6, 0x55, 0xA5, 0x55]);
// Test the time for 16 KiB of input
$input = array_merge(...array_fill(0, 1024, [0x10, 0xFF, 0x00, 0xAA, 0x55, 0x12, 0x34, 0x56, 0x78, 0x90, 0x01, 0x02, 0x03, 0xF1, 0xF2, 0xF3]));
$output = array_merge(...array_fill(0, 1024, [0xAA, 0xA9, 0x55, 0x55, 0xAA, 0xAA, 0x66, 0x66, 0x99, 0x99, 0xA6, 0xA9, 0x9A, 0xA5, 0x96, 0x99, 0x6A, 0x95, 0xAA, 0x69, 0xA9, 0xAA, 0xA6, 0xAA, 0xA5, 0xAA, 0xA9, 0x55, 0xA6, 0x55, 0xA5, 0x55]));
printf("Size of input: %d bytes\n", count($input));
$this->testCase($input, $output);
// Test the time for 1 Mib of input
$input = array_merge(...array_fill(0, 16*4096, [0x10, 0xFF, 0x00, 0xAA, 0x55, 0x12, 0x34, 0x56, 0x78, 0x90, 0x01, 0x02, 0x03, 0xF1, 0xF2, 0xF3]));
$output = array_merge(...array_fill(0, 16*4096, [0xAA, 0xA9, 0x55, 0x55, 0xAA, 0xAA, 0x66, 0x66, 0x99, 0x99, 0xA6, 0xA9, 0x9A, 0xA5, 0x96, 0x99, 0x6A, 0x95, 0xAA, 0x69, 0xA9, 0xAA, 0xA6, 0xAA, 0xA5, 0xAA, 0xA9, 0x55, 0xA6, 0x55, 0xA5, 0x55]));
printf("Size of input: %d bytes\n", count($input));
$this->testCase($input, $output);
}
public function getTheGolfedCode()
{
// Enclose the code into a function
return sprintf('function f($i){%s}', parent::getFunctionBody('Mnchstr2', __CLASS__));
}
public function runTheGolfedCode($argc, array $argv)
{
echo (implode(' ', $this->Mnchstr2(array_slice($argv, 1))))."\n";
}
/////////////////////////////////////////////////////////////////////////
// Test helpers
//
/**
* @param int[] $input the string to unscramble
* @param string[] $expected the expected output (the unscrambled string)
*/
protected function testCase(array $input, array $expected)
{
$ts = microtime(TRUE);
$actual = $this->Manchester1($input);
$time = microtime(TRUE) - $ts;
it(sprintf('encodes using the Manchester clear code #1 (time: %.8f sec)', $time), $actual == $expected);
$ts = microtime(TRUE);
$actual = $this->Mnchstr1($input);
$time = microtime(TRUE) - $ts;
it(sprintf('encodes using the Manchester golfed code #1 (time: %.8f sec)', $time), $actual == $expected);
$ts = microtime(TRUE);
$actual = $this->Manchester2($input);
$time = microtime(TRUE) - $ts;
it(sprintf('encodes using the Manchester clear code #2 (time: %.8f sec)', $time), $actual == $expected);
$ts = microtime(TRUE);
$actual = $this->Mnchstr2($input);
$time = microtime(TRUE) - $ts;
it(sprintf('encodes using the Manchester golfed code #2 (time: %.8f sec)', $time), $actual == $expected);
}
protected function Manchester1(array $input)
{
return array_merge(
...array_map(
function ($number) {
return array_reverse(
array_map(
'bindec',
str_split(
str_replace(
['0', '1', '2'],
['2', '01', '10'],
str_pad(decbin($number), 8, '0', STR_PAD_LEFT)
), 8
)
)
);
},
$input
)
);
}
protected function Mnchstr1(array $i)
{
return array_merge(...array_map(function($number){return array_reverse(array_map(bindec,str_split(str_replace([0,1,2],[2,'01',10],str_pad(decbin($number),8,0,0)),8)));},$i));
}
protected function Manchester2(array $input)
{
$output = [];
foreach ($input as $number) {
$bytes = str_split(
str_replace(
['0', '1', '2'],
['2', '01', '10'],
str_pad(decbin($number), 8, '0', STR_PAD_LEFT)
),
8
);
$output[] = bindec($bytes[1]);
$output[] = bindec($bytes[0]);
}
return $output;
}
protected function Mnchstr2(array $i)
{
foreach($i as$n){$b=str_split(str_replace([0,1,2],[2,'01',10],str_pad(decbin($n),8,0,0)),8);$o[]=bindec($b[1]);$o[]=bindec($b[0]);}return$o;
}
}
(new ManchesterEncodeADataStream($argc, $argv))->run();
// This is the end of file; no closing PHP tag