package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
)

// Part 1 Disk Size: 272
// Part 2 Disk Size: 35651584
func main() {
	diskSize := 272
	if len(os.Args) > 1 {
		switch os.Args[1] {
		case "-2":
			// Do part two
			diskSize = 35651584
		default:
			// manually set disk size
			diskSize = atoi(os.Args[1])
		}
	}
	input := stdinToString()
	for len(input) < diskSize {
		input = dragonCurve(input)
	}
	input = input[:diskSize]
	fmt.Println(checksum(input))
}

func dragonCurve(inp string) string {
	return inp + "0" + invert(reverse(inp))
}

func invert(inp string) string {
	var ret []rune
	for i := range inp {
		if inp[i] == '1' {
			ret = append(ret, '0')
		} else {
			ret = append(ret, '1')
		}
	}
	return string(ret)
}

func reverse(inp string) string {
	var ret []byte
	for i := len(inp) - 1; i >= 0; i-- {
		ret = append(ret, inp[i])
	}
	return string(ret)
}

func checksum(inp string) string {
	var chkSum []rune
	for i := 0; i < len(inp); i += 2 {
		if inp[i] == inp[i+1] {
			chkSum = append(chkSum, '1')
		} else {
			chkSum = append(chkSum, '0')
		}
	}
	if len(chkSum)%2 == 0 {
		// Length is even, repeat
		return checksum(string(chkSum))
	}
	return string(chkSum)
}

func stdinToString() string {
	var input string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input += scanner.Text()
	}
	return input
}

func atoi(i string) int {
	var ret int
	var err error
	if ret, err = strconv.Atoi(i); err != nil {
		log.Fatal("Invalid Atoi")
	}
	return ret
}
