commit c53dbc278c89a74361f379a21e76fe028686a475
parent eef434e314ef6b71370c426e7e443f19d29b2d2d
Author: david cochran <about.trout@gmail.com>
Date: Mon, 31 Jan 2022 02:47:35 +0000
add layer2 solution
Diffstat:
3 files changed, 86 insertions(+), 0 deletions(-)
diff --git a/bitwise.go b/bitwise.go
@@ -12,3 +12,24 @@ func FlipSecondBits(b byte) byte {
func CycleRight(b byte) byte {
return (b << 7) | (b >> 1)
}
+
+func ParityCheck(b byte) bool {
+ p := bits.OnesCount8(b&0b11111110) % 2
+ return p == int(b%2)
+}
+
+func PackDataBytes(bs []byte) []byte {
+ if len(bs)%8 != 0 {
+ log.Fatalf("Failed to PackDataBytes: input slice of length %d, not a multiple of 8", len(bs))
+ }
+ var out []byte
+ for i := 0; i < len(bs)/8; i++ {
+ for j := 0; j < 7; j++ {
+ k := i*8 + j // index in bs
+ left := (bs[k] >> 1) << (j + 1)
+ right := bs[k+1] >> (7 - j)
+ out = append(out, left|right)
+ }
+ }
+ return out
+}
diff --git a/bitwise_test.go b/bitwise_test.go
@@ -33,3 +33,43 @@ func TestFlipSecondBits(t *testing.T) {
}
}
}
+
+func TestParityCheck(t *testing.T) {
+ tests := []struct {
+ in byte
+ want bool
+ }{
+ {0b10100011, true},
+ {0b10100010, false},
+
+ {0b11111111, true},
+ {0b11111110, false},
+
+ {0b00000000, true},
+ {0b00000001, false},
+ }
+
+ for _, test := range tests {
+ if got := ParityCheck(test.in); got != test.want {
+ t.Errorf("ParityCheck(%08b) = %t; want %t", test.in, got, test.want)
+ }
+ }
+}
+
+func TestPackDataBytes(t *testing.T) {
+ in := []byte{
+ 0b11111110, 0b11111110, 0b11111110, 0b11111110,
+ 0b11111110, 0b11111110, 0b11111110, 0b11111110,
+ 0b11111110, 0b11111110, 0b11111110, 0b11111110,
+ 0b11111110, 0b11111110, 0b11111110, 0b11111110,
+ }
+ want := []byte{
+ 0b11111111, 0b11111111, 0b11111111, 0b11111111,
+ 0b11111111, 0b11111111, 0b11111111, 0b11111111,
+ 0b11111111, 0b11111111, 0b11111111, 0b11111111,
+ 0b11111111, 0b11111111,
+ }
+ if got := PackDataBytes(in); !bytes.Equal(got, want) {
+ t.Errorf("PackDataBytes(%#v) = %#v (len %d); want %#v (len %d)", in, got, len(got), want, len(want))
+ }
+}
diff --git a/cmd/layer2/decode.go b/cmd/layer2/decode.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+ "log"
+ "os"
+
+ "github.com/abtrout/tdo"
+)
+
+func main() {
+ bs, err := tdo.DecodePipedInput()
+ if err != nil {
+ log.Fatalf("Failed to read layer input: %v", err)
+ }
+ var filtered []byte
+ for _, b := range bs {
+ if tdo.ParityCheck(b) {
+ filtered = append(filtered, b)
+ }
+ }
+ out := tdo.PackDataBytes(filtered)
+ if _, err := os.Stdout.Write(out); err != nil {
+ log.Fatalf("Failed to write decoded output: %v", err)
+ }
+}