Skip to content

Instantly share code, notes, and snippets.

@okaq
Created April 15, 2014 18:01
Show Gist options
  • Save okaq/10753486 to your computer and use it in GitHub Desktop.
Save okaq/10753486 to your computer and use it in GitHub Desktop.
Google Code Jam 2014 Qualification Round * Problem A. Magic Trick
/*
* Google Code Jam 2014 Qualification Round
* Problem A. Magic Trick
* execute with: go run A.go < A-small-practice.in > A-small-practice.out
*/
package main
import (
"fmt"
"strconv"
"sync"
)
var (
// Global to hold number of test cases.
T int
// Wait Group necessary for synchronizing.
WG sync.WaitGroup
// Answers map {testcase: result}.
A map[int]string
)
// Magic Trick struct
type Trick struct {
Guess int
Cards []int
}
// Load tricks from input file helper.
func LoadTrick() *Trick {
t := new(Trick)
_, err := fmt.Scan(&t.Guess)
if err != nil {
fmt.Println(err)
}
t.Cards = make([]int, 16)
for i := 0; i < 16; i++ {
_, err := fmt.Scan(&t.Cards[i])
if err != nil {
fmt.Println(err)
}
}
return t
}
// Return a row sub-slice from the board.
func (t *Trick) Row(r int) []int {
return t.Cards[4*r : 4*r+4]
}
// Get number of test cases from first line of file.
func NumCases() {
_, err := fmt.Scan(&T)
if err != nil {
fmt.Println(err)
}
}
// Split tests cases.
func Splitter() {
for i := 0; i < T; i++ {
// "Every great magic trick consists of three acts!"
pledge := LoadTrick()
turn := LoadTrick()
// Synchronize wait group.
WG.Add(1)
// Launch separate goroutine to solve each test case.
go Solve(pledge, turn, i)
}
}
// Analyze two rows for repeated values. Return count, final guess.
func Prestige(a, b []int) (int, int) {
// tally
t := make(map[int]int)
for i := 0; i < len(a); i++ {
t[a[i]]++
t[b[i]]++
}
// count repeated numbers in the two rows
count := 0
guess := 0
for k, _ := range t {
if t[k] > 1 {
count++
guess = k
}
}
return count, guess
}
// Solver.
func Solve(p, t *Trick, testcase int) {
defer WG.Done()
pr := p.Row(p.Guess - 1)
tr := t.Row(t.Guess - 1)
c, g := Prestige(pr, tr)
if c == 1 {
A[testcase] = strconv.Itoa(g)
}
if c > 1 {
A[testcase] = "Bad magician!"
}
if c < 1 {
A[testcase] = "Volunteer cheated!"
}
}
// Write results to STDOUT.
func Output() {
for i := 0; i < T; i++ {
fmt.Printf("Case #%d: %s\n", i+1, A[i])
}
}
func main() {
NumCases()
A = make(map[int]string)
Splitter()
WG.Wait()
Output()
}
// C-style I/O (scan,printf)
// with args fed via STDIN, STDOUT
// Prefer to handle files in program
// with const paths.
// I/O via bufio pkg.
// Then err and program stats
// such as timing can be written to console.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment