Skip to content

Instantly share code, notes, and snippets.

@koizuka
Created July 19, 2014 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koizuka/154721349855b38dcbcf to your computer and use it in GitHub Desktop.
Save koizuka/154721349855b38dcbcf to your computer and use it in GitHub Desktop.
SECCON-2014 あみだくじ
package main
import (
"fmt"
"log"
"os/exec"
"strings"
)
func main() {
amida := exec.Command("./amida")
cin,err := amida.StdinPipe()
if err != nil {
log.Fatal(err)
}
cout,err := amida.StdoutPipe()
if err != nil {
log.Fatal(err)
}
err = amida.Start()
if err != nil {
log.Fatal(err)
}
// problem loop
for {
lines := make([][]byte, 0, 100)
maxWidth := 0
// lines loop
for {
line := make([]byte, 0, 100)
done := false
// read a line
for {
buf := make([]byte, 1, 1)
n, err := cout.Read(buf)
c := buf[0]
if n != 1 {
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
}
if c == 0 {
continue
}
if c == '\n' {
break
}
if c == '?' {
done = true
break
}
line = append(line, c)
}
fmt.Println(string(line[:]))
if strings.Contains(string(line[:]), "No.") {
// clear
lines = lines[:0]
maxWidth = 0
} else if len(line) > 0 {
lines = append(lines, line)
if len(line) > maxWidth {
maxWidth = len(line)
}
}
if done {
break
}
}
// rotate
if strings.Contains(string(lines[0][:]), "--") {
fmt.Println("rotate!")
// rotate 90 degree
newLines := make([][]byte, 0, 100)
for y := 0; y < maxWidth; y++ {
newLine := make([]byte, 0, len(lines))
for _, line := range lines {
var b byte = ' '
if len(line) > y {
b = line[y]
switch b {
case '-':
b = '|'
break
case '|':
b = '-'
break
}
}
newLine = append(newLine, b)
}
newLines = append(newLines, newLine)
}
lines = newLines
}
// upside down
if strings.Contains(string(lines[0][:]), "*") {
newLines := make([][]byte, 0, 100)
for i := range lines {
newLines = append(newLines, lines[len(lines) - 1 - i])
}
lines = newLines
}
fmt.Println("board:")
for _, line := range lines {
fmt.Println(string(line[:]))
}
labels := make(map[int]byte)
positions := make(map[int]int)
for i := 0; i < 8; i++ {
positions[i] = i
}
offsets := make([]int, 8, 8)
goal := -1
for _, line := range lines {
switch line[0] {
case '1', '2', '3', '4', '5', '6', '7', '8':
i := 0
for x,c := range line {
if c >= '1' && c <= '8' {
offsets[i] = x
labels[i] = c
i++
}
}
break
case '|':
i := -1
ignore := true
for _,c := range line {
switch c {
case '|':
ignore = false
i++
break
case '-':
if !ignore {
positions[i], positions[i+1] = positions[i+1], positions[i]
ignore = true
}
break
}
}
break
case ' ', '*':
for i, c := range line {
if c == '*' {
goal = i
}
}
break
}
}
for i := range offsets {
if goal == offsets[i] {
goal = i
break
}
}
fmt.Printf("goal = %d\n", goal)
answer := labels[positions[goal]]
fmt.Printf("answer = %c\n", answer)
fmt.Fprintf(cin, "%c\n", answer)
}
}
/*
No.1
1 2 3 4 5 6 7 8
|-| |-| | | |-|
| | | | | |-| |
| | | | | | |-|
|-| | |-| | | |
| | |-| |-| |-|
|-| | |-| | | |
| |-| | |-| |-|
|-| |-| | | | |
| | | | |-| | |
| | |-| | | |-|
|-| | | |-| | |
| | |-| | |-| |
| | | | |-| | |
| |-| | | |-| |
| | |-| | | |-|
| | | | | |-| |
| |-| | |-| |-|
|-| |-| | | | |
| | | | | |-| |
*
? 1
Wrong.
*/
// vim: nu si aw ts=4 sw=4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment