mirror of
https://github.com/Luzifer/codingame-solutions.git
synced 2024-12-23 03:01:25 +00:00
Add two new solutions
This commit is contained in:
parent
dd9a6c9db0
commit
1ea0dddd6d
3 changed files with 314 additions and 0 deletions
|
@ -9,5 +9,7 @@ Just one thing: **Don't just copy them.** Take the puzzle yourself and afterward
|
||||||
- Medium
|
- Medium
|
||||||
- [Don't Panic - Episode 1](https://www.codingame.com/training/medium/don't-panic-episode-1)
|
- [Don't Panic - Episode 1](https://www.codingame.com/training/medium/don't-panic-episode-1)
|
||||||
- [Shadows of the Knight - Episode 1](https://www.codingame.com/training/medium/shadows-of-the-knight-episode-1)
|
- [Shadows of the Knight - Episode 1](https://www.codingame.com/training/medium/shadows-of-the-knight-episode-1)
|
||||||
|
- [Bender - Episode 1](https://www.codingame.com/training/medium/bender-episode-1)
|
||||||
|
- [There is no Spoon - Episode 1](https://www.codingame.com/training/medium/there-is-no-spoon-episode-1)
|
||||||
- Community
|
- Community
|
||||||
- [Texas Holdem](https://www.codingame.com/training/community/texas-holdem) by AdamHill
|
- [Texas Holdem](https://www.codingame.com/training/community/texas-holdem) by AdamHill
|
||||||
|
|
201
finished/medium_bender-episode-1.go
Normal file
201
finished/medium_bender-episode-1.go
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type direction string
|
||||||
|
|
||||||
|
const (
|
||||||
|
SOUTH direction = "SOUTH"
|
||||||
|
WEST = "WEST"
|
||||||
|
EAST = "EAST"
|
||||||
|
NORTH = "NORTH"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MAP_TILE_OBSTACLE byte = 'X'
|
||||||
|
MAP_TILE_WALL = '#'
|
||||||
|
MAP_TILE_EAST = 'E'
|
||||||
|
MAP_TILE_WEST = 'W'
|
||||||
|
MAP_TILE_NORTH = 'N'
|
||||||
|
MAP_TILE_SOUTH = 'S'
|
||||||
|
MAP_TILE_BEER = 'B'
|
||||||
|
MAP_TILE_INVERT = 'I'
|
||||||
|
MAP_TILE_START = '@'
|
||||||
|
MAP_TILE_TELEPORTER = 'T'
|
||||||
|
MAP_TILE_FLOOR = ' '
|
||||||
|
MAP_TILE_DEATH = '$'
|
||||||
|
MAP_TILE_OUT_OF_BOUNDS = '?' // Internal error-reporter
|
||||||
|
)
|
||||||
|
|
||||||
|
var directionChange = map[bool][]direction{
|
||||||
|
false: []direction{SOUTH, EAST, NORTH, WEST},
|
||||||
|
true: []direction{WEST, NORTH, EAST, SOUTH},
|
||||||
|
}
|
||||||
|
|
||||||
|
type point struct{ X, Y int }
|
||||||
|
|
||||||
|
func (p point) Next(d direction) point {
|
||||||
|
switch d {
|
||||||
|
case SOUTH:
|
||||||
|
return point{p.X, p.Y + 1}
|
||||||
|
case WEST:
|
||||||
|
return point{p.X - 1, p.Y}
|
||||||
|
case NORTH:
|
||||||
|
return point{p.X, p.Y - 1}
|
||||||
|
case EAST:
|
||||||
|
return point{p.X + 1, p.Y}
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
type playground struct {
|
||||||
|
Source string
|
||||||
|
Width, Height int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p playground) Get(pt point) byte {
|
||||||
|
pos := pt.Y*p.Width + pt.X
|
||||||
|
if pos >= len(p.Source) {
|
||||||
|
return MAP_TILE_OUT_OF_BOUNDS
|
||||||
|
}
|
||||||
|
return p.Source[pos]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *playground) Set(pt point, mapReplace byte) {
|
||||||
|
pos := pt.Y*p.Width + pt.X
|
||||||
|
tmp := []byte(p.Source)
|
||||||
|
tmp[pos] = mapReplace
|
||||||
|
p.Source = string(tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p playground) FindUniquePOI(poi byte) point {
|
||||||
|
pos := strings.IndexByte(p.Source, poi)
|
||||||
|
return point{X: pos % p.Width, Y: pos / p.Width}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p playground) FindMultiplePOI(poi byte) []point {
|
||||||
|
out := []point{}
|
||||||
|
|
||||||
|
for pos := 0; pos < len(p.Source); pos++ {
|
||||||
|
if p.Source[pos] == poi {
|
||||||
|
out = append(out, point{X: pos % p.Width, Y: pos / p.Width})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
type bender struct {
|
||||||
|
City playground
|
||||||
|
|
||||||
|
Position point
|
||||||
|
BeerMode bool
|
||||||
|
InvertMode bool
|
||||||
|
MoveDirection direction
|
||||||
|
|
||||||
|
path []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *bender) Init() {
|
||||||
|
b.Position = b.City.FindUniquePOI(MAP_TILE_START)
|
||||||
|
b.MoveDirection = SOUTH
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b bender) Path() string {
|
||||||
|
return strings.Join(b.path, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *bender) Trace(maxSteps int) error {
|
||||||
|
madeSteps := 0
|
||||||
|
|
||||||
|
for madeSteps < maxSteps {
|
||||||
|
nextPos := b.Position.Next(b.MoveDirection)
|
||||||
|
|
||||||
|
nd := 0
|
||||||
|
for b.City.Get(nextPos) == MAP_TILE_OBSTACLE || b.City.Get(nextPos) == MAP_TILE_WALL {
|
||||||
|
if b.BeerMode && b.City.Get(nextPos) == MAP_TILE_OBSTACLE {
|
||||||
|
b.City.Set(nextPos, MAP_TILE_FLOOR)
|
||||||
|
} else {
|
||||||
|
b.MoveDirection = directionChange[b.InvertMode][nd]
|
||||||
|
nextPos = b.Position.Next(b.MoveDirection)
|
||||||
|
nd++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Position = nextPos
|
||||||
|
log.Printf("Moved to %#v", b.Position)
|
||||||
|
b.path = append(b.path, string(b.MoveDirection))
|
||||||
|
|
||||||
|
switch b.City.Get(b.Position) {
|
||||||
|
case MAP_TILE_START:
|
||||||
|
return errors.New("Returned to start, no cool.")
|
||||||
|
case MAP_TILE_OUT_OF_BOUNDS:
|
||||||
|
return errors.New("Bender left the map. How?!?")
|
||||||
|
case MAP_TILE_WEST:
|
||||||
|
b.MoveDirection = WEST
|
||||||
|
case MAP_TILE_EAST:
|
||||||
|
b.MoveDirection = EAST
|
||||||
|
case MAP_TILE_SOUTH:
|
||||||
|
b.MoveDirection = SOUTH
|
||||||
|
case MAP_TILE_NORTH:
|
||||||
|
b.MoveDirection = NORTH
|
||||||
|
case MAP_TILE_BEER:
|
||||||
|
b.BeerMode = !b.BeerMode
|
||||||
|
case MAP_TILE_INVERT:
|
||||||
|
b.InvertMode = !b.InvertMode
|
||||||
|
case MAP_TILE_DEATH:
|
||||||
|
// We got killed. Bye cruel world!
|
||||||
|
return nil
|
||||||
|
case MAP_TILE_TELEPORTER:
|
||||||
|
teleporters := b.City.FindMultiplePOI(MAP_TILE_TELEPORTER)
|
||||||
|
for i := range teleporters {
|
||||||
|
t := teleporters[i]
|
||||||
|
if t.X == b.Position.X && t.Y == b.Position.Y {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b.Position = t
|
||||||
|
log.Printf("Bzzzzp. Now at: %#v", b.Position)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
madeSteps++
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("Max steps reached. (LOOP)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
|
||||||
|
var L, C int
|
||||||
|
scanner.Scan()
|
||||||
|
fmt.Sscan(scanner.Text(), &L, &C)
|
||||||
|
|
||||||
|
b := &bender{}
|
||||||
|
b.City.Width = C
|
||||||
|
b.City.Height = L
|
||||||
|
|
||||||
|
for i := 0; i < L; i++ {
|
||||||
|
scanner.Scan()
|
||||||
|
b.City.Source = b.City.Source + scanner.Text()
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Init()
|
||||||
|
|
||||||
|
log.Printf("%#v", b)
|
||||||
|
|
||||||
|
if err := b.Trace(L * C); err != nil {
|
||||||
|
log.Printf("Trace error: %s", err)
|
||||||
|
fmt.Println("LOOP")
|
||||||
|
} else {
|
||||||
|
fmt.Println(b.Path())
|
||||||
|
}
|
||||||
|
}
|
111
finished/medium_there-is-no-spoon-episode-1.go
Normal file
111
finished/medium_there-is-no-spoon-episode-1.go
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CHAR_NODE = '0'
|
||||||
|
CHAR_FREE = '.'
|
||||||
|
)
|
||||||
|
|
||||||
|
type playground struct {
|
||||||
|
Source string
|
||||||
|
Width, Height int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p playground) Scan() <-chan string {
|
||||||
|
log.Printf("%#v", p)
|
||||||
|
c := make(chan string, 100)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer close(c)
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
for i := 0; i < len(p.Source); i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(i int) {
|
||||||
|
defer wg.Done()
|
||||||
|
x := i % p.Width
|
||||||
|
y := i / p.Width
|
||||||
|
if p.get(x, y) != CHAR_NODE {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("X: %d Y: %d", x, y)
|
||||||
|
|
||||||
|
c <- p.GetNeighborNotation(x, y)
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}()
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p playground) get(x, y int) byte {
|
||||||
|
pos := y*p.Width + x
|
||||||
|
log.Printf("Getting x=%d y=%d (str=%d, char=%c", x, y, pos, p.Source[pos])
|
||||||
|
if pos >= len(p.Source) {
|
||||||
|
return '?'
|
||||||
|
}
|
||||||
|
return p.Source[pos]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p playground) GetNeighborNotation(x, y int) string {
|
||||||
|
bx, by := p.getBottomNext(x, y+1)
|
||||||
|
rx, ry := p.getRightNext(x+1, y)
|
||||||
|
return fmt.Sprintf("%d %d %d %d %d %d", x, y, rx, ry, bx, by)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p playground) getBottomNext(x, y int) (int, int) {
|
||||||
|
if y >= p.Height {
|
||||||
|
return -1, -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.get(x, y) == CHAR_NODE {
|
||||||
|
return x, y
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.getBottomNext(x, y+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p playground) getRightNext(x, y int) (int, int) {
|
||||||
|
if x >= p.Width {
|
||||||
|
return -1, -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.get(x, y) == CHAR_NODE {
|
||||||
|
return x, y
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.getRightNext(x+1, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
|
||||||
|
// width: the number of cells on the X axis
|
||||||
|
var width int
|
||||||
|
scanner.Scan()
|
||||||
|
fmt.Sscan(scanner.Text(), &width)
|
||||||
|
|
||||||
|
// height: the number of cells on the Y axis
|
||||||
|
var height int
|
||||||
|
scanner.Scan()
|
||||||
|
fmt.Sscan(scanner.Text(), &height)
|
||||||
|
|
||||||
|
pg := playground{Width: width, Height: height}
|
||||||
|
|
||||||
|
for i := 0; i < height; i++ {
|
||||||
|
scanner.Scan()
|
||||||
|
pg.Source = pg.Source + scanner.Text()
|
||||||
|
}
|
||||||
|
|
||||||
|
for out := range pg.Scan() {
|
||||||
|
fmt.Println(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue