previndexinfonext

code guessing, round #35 (completed)

started at ; stage 2 at ; ended at

specification

apparently we have to play sokoban. programs can be written in python, lua, c#, or sed.

sokoban is a fucking annoying puzzle game that you have probably had the misfortune of playing before in one way or another. the idea is simple. everything takes place on a grid consisting of movable boxes, immovable walls and the player. the player can move in any of the 4 orthogonal directions, and will push any movable boxes in front of them in the process.

the goal of the game is usually to get certain boxes into certain positions, but thankfully today I'll only be asking you to simulate the physics system. we'll represent the player as a negative number, empty space as 0, boxes as positive numbers less than the absolute value of the player, and walls as greater values. unusually, you can push more than one box at once.

as an example, if the board looks like this:

0  0  0  0  0  0
0  0  1  0  0  0
0  6 -3  3  2  0

the player is the -3 tile. if they move left or down, nothing happens. if they move up, they shift the 1 tile:

0  0  1  0  0  0
0  0 -3  0  0  0
0  6  0  3  2  0

and if they move right, they shift two tiles:

0  0  0  0  0  0
0  0  1  0  0  0
0  6  0 -3  3  2

your challenge, given a row-major grid and a string of moves (W, A, S, or D), is to return the resulting board after the moves are applied.

APIs:

results

  1. 👑 LyricLy +2 -1 = 1
    1. olus2000
    2. seshoumara
  2. olus2000 +2 -1 = 1
    1. LyricLy
    2. seshoumara
  3. seshoumara +0 -2 = -2
    1. LyricLy (was olus2000)
    2. olus2000 (was LyricLy)

entries

you can download all the entries

entry #1

written by olus2000
submitted at
0 likes

guesses
comments 6
olus2000

Try it online at: https://www.lexaloffle.com/bbs/?tid=52273&tkey=n7PADkjhhtLyCzztIg6D

It also has link to source code online


olus2000

haha i just came to a realization


RocketRace

i have the ability to mimic any individual in this manner


olus2000

So bad...


olus2000

You can't mimic me (no capital letter at the start of a sentence)


verified


post a comment


cg_35.p8.png PNG image data, 160 x 205, 8-bit/color RGBA, non-interlaced

entry #2

written by LyricLy
submitted at
0 likes

guesses
comments 0

post a comment


outoftime.py ASCII text, with CRLF line terminators
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
def shunt(fuck, me, sideways, where):
    x, y = where[0] + sideways[0], where[1] + sideways[1]
    if fuck[y][x] > me:
        return False
    if fuck[y][x] and not shunt(fuck, me, (x, y), where):
         return False
    fuck[y][x], fuck[where[1]][where[0]] = fuck[where[1]][where[0]], fuck[y][x]
    return True

def epic(fuck, help):
   for j, y in enumerate(fuck):
       for i, x in enumerate(y):
            if x < 0:
                shunt(fuck, abs(x), (i, j), (0, -1) if help == "W" else (-1, 0) if help == "A" else (0, 1) if help == "S" else (1, 0))
                return

def entry(fuck, shit):
    for help in shit:
        epic(fuck, help)
    return fuck

entry #3

written by seshoumara
submitted at
0 likes

guesses
comments 0

post a comment


cg35__sokoban.sed ASCII text
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/sed -nrsf

:_Problem
	# sokoban derivative (only the physics system)
	# https://cg.esolangs.gay/35/
:_Restrictions
	# Tile values are only in [0-9] range and board size is fixed at 6x6.


:main
	#test if GNU extensions are supported
	1v

	#store input data, then parse the moves (first line) and the board (remaining 6 lines)
	H
	1{
		/[WASD]/!{
			s/.*/Error: no moves, [WASD]+, found on line 1!/
			p;q
		}
	}
	2,${
		/^(-?[0-9][ \t]*){6}$/!{
			s/.*/Error: board size must be 6x6, with each tile having a value in [0-9] range!/
			p;q
		}
	}
	$!d
	g
	s:^\n[^\n]+::
	/(\n[^\n]+){6}/!{
		s/.*/Error: board size must be 6x6!/
		p;q
	}
	s:[0-9 \t\n]::g
	/^-$/!{
		s/.*/Error: exactly one tile, the player, must have its value prepended with '-' (negative value)!/
		p;q
	}
	x
	s: ::g

	#print input state
	s/^\n/\nInput state:\n()/p
	s:^\n[^\n]+\n\(\)::
	x

	s/.*/Intermediary states:/p
	:loop
		g
		#call one_move, save resulting state, then discard the move
		b one_move
		:return
			h;x
			s:^[WASD]::
			x
		#print intermediary state (skip if output state reached) and loop again if needed
		s:^[WASD]:(&):
		/^\([WASD]\)\n/!p
	/^\([WASD]\)\n/!b loop

	#print output state
	s/^/Output state:\n/p
b EOS


:one_move
	#index the board
	s:\n(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])\n:\n,0=\1,1=\2,2=\3,3=\4,4=\5,5=\6\n@:
	s:@(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])\n:,6=\1,7=\2,8=\3,9=\4,10=\5,11=\6\n@:
	s:@(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])\n:,12=\1,13=\2,14=\3,15=\4,16=\5,17=\6\n@:
	s:@(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])\n:,18=\1,19=\2,20=\3,21=\4,22=\5,23=\6\n@:
	s:@(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])\n:,24=\1,25=\2,26=\3,27=\4,28=\5,29=\6\n@:
	s:@(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9])(-?[0-9]):,30=\1,31=\2,32=\3,33=\4,34=\5,35=\6:

	#setup number line and the tile adjacency table (lazy to calculate it)
        s:$:\nL0112233445566778899L:
	s:-([0-9])(.*L[0-9]+)\1\1:-\1\2\1-\1:
	s:$:<ADJ>,0-S6D1,1-S7A0D2,2-S8A1D3,3-S9A2D4,4-S10A3D5,5-S11A4:
	s:$:,6-W0S12D7,7-W1S13A6D8,8-W2S14A7D9,9-W3S15A8D10,10-W4S16A9D11,11-W5S17A10:
	s:$:,12-W6S18D13,13-W7S19A12D14,14-W8S20A13D15,15-W9S21A14D16,16-W10S22A15D17,17-W11S23A16:
	s:$:,18-W12S24D19,19-W13S25A18D20,20-W14S26A19D21,21-W15S27A20D22,22-W16S28A21D23,23-W17S29A22:
	s:$:,24-W18S30D25,25-W19S31A24D26,26-W20S32A25D27,27-W21S33A26D28,28-W22S34A27D29,29-W23S35A28:
	s:$:,30-W24D31,31-W25A30D32,32-W26A31D33,33-W27A32D34,34-W28A33D35,35-W29A34,<JDA>:

	#skip current move since player is already at the edge of the board
	/^([WASD]).*,([0-9][0-9]?)=-.*<ADJ>.*,\2-[^,]*\1/!{
		s/^[WASD]/Warning: current move & is skipped since the player is already at the edge of the board!\n&/
		P
		b skip
	}

	s:=-:=+-:
	:construct_path
		#from current player/box get the next tile in direction of current move
		s:^([WASD])(.*,)([0-9][0-9]?)(=\+.*<ADJ>.*,)\3(-[^,]*)\1([0-9][0-9]?):\6\n&:
		s:=\+:=@:
		#if next tile is an empty space, the path of tiles to move was finished, call apply_move
		/^([0-9][0-9]?)\n.*,\1=0/b apply_move
		#if next tile is a wall, skip current move
		/^([0-9][0-9]?)\n.*,\1=([0-9]).*L[0-9]+\2[0-9]*-/!{
			s/^[^\n]+\n([WASD])/Warning: current move \1 is skipped because of a blocking wall!\n\1/
			P
			b skip
		}
		#next tile is a box, mark it with + to become new current box from now on
		s:^([0-9][0-9]?)(\n.*,)\1=([0-9])(.*L[0-9]+)\3([0-9]*-):\1\2\1=+\3\4\3\5:
		s:^[^\n]+\n::
		#skip current move since current box is already at the edge of the board
		/^([WASD]).*,([0-9][0-9]?)=\+.*<ADJ>.*,\2-[^,]*\1/!{
			s/^[WASD]/Warning: current move & is skipped since last moveable box is already at the edge of the board!\n&/
			P
			b skip
		}
	b construct_path

	:apply_move
		#transform current move into opposite move, to go from empty space back to player
		s:\n[WASD]:& ,W->S,S->W,A->D,D->A :
		s:\n([WASD]) [^\n]*,\1->([WASD])[^\n]* :\n\2\n\1:

		:shift
			#call skip to finish, if current tile is already at the edge of the board
			/^([0-9][0-9]?)\n([WASD]).*<ADJ>.*,\1-[^,]*\2/!{
				s:^[^\n]+\n::
				b skip
			}
			#from current tile get the next tile in opposite direction of current move
			s:^([0-9][0-9]?)\n([WASD])(.*<ADJ>.*,)\1(-[^,]*)\2([0-9][0-9]?):\1 \5\n\2\3\1\4\2\5:
			#if next tile isn't marked with @, path was already shifted, call skip to finish
			/^[0-9][0-9]? ([0-9][0-9]?)\n.*,\1=@/!{
				s:^[^\n]+\n::
				b skip
			}
			#swap values of current tile and next tile, with next tile to become new current tile
			s:^([0-9][0-9]?) ([0-9][0-9]?)(\n.*,)\1=0(.*,)\2=(@-?[0-9]):\2\3\1=\5\4\2=0:
			s:^([0-9][0-9]?) ([0-9][0-9]?)(\n.*,)\2=(@-?[0-9])(.*,)\1=0:\2\3\2=0\5\1=\4:
		b shift

	:skip
		s:^[^\n]+\n::
		#strip tile markings
		s:=@:=:g
		s:=\+:=:g
		#remove the number line and the tile adjacency table, then strip the board index (for pretty printing back in main)
		s:\nL.*$::
		s:,[0-9][0-9]?=::g
b return


:EOS
	#End Of Script (mainly used to skip over remaining code, when needed)
cg35_complicated.txt ASCII text
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
Input state:
()SAAWWWDDSSSSWWWDSSSWWWDSSS
000000
001000
06-3320
000000
000000
000000
Intermediary states:
(S)AAWWWDDSSSSWWWDSSSWWWDSSS
000000
001000
060320
00-3000
000000
000000
(A)AWWWDDSSSSWWWDSSSWWWDSSS
000000
001000
060320
0-30000
000000
000000
(A)WWWDDSSSSWWWDSSSWWWDSSS
000000
001000
060320
-300000
000000
000000
(W)WWDDSSSSWWWDSSSWWWDSSS
000000
001000
-360320
000000
000000
000000
(W)WDDSSSSWWWDSSSWWWDSSS
000000
-301000
060320
000000
000000
000000
(W)DDSSSSWWWDSSSWWWDSSS
-300000
001000
060320
000000
000000
000000
(D)DSSSSWWWDSSSWWWDSSS
0-30000
001000
060320
000000
000000
000000
(D)SSSSWWWDSSSWWWDSSS
00-3000
001000
060320
000000
000000
000000
(S)SSSWWWDSSSWWWDSSS
000000
00-3000
061320
000000
000000
000000
(S)SSWWWDSSSWWWDSSS
000000
000000
06-3320
001000
000000
000000
(S)SWWWDSSSWWWDSSS
000000
000000
060320
00-3000
001000
000000
(S)WWWDSSSWWWDSSS
000000
000000
060320
000000
00-3000
001000
(W)WWDSSSWWWDSSS
000000
000000
060320
00-3000
000000
001000
(W)WDSSSWWWDSSS
000000
000000
06-3320
000000
000000
001000
(W)DSSSWWWDSSS
000000
00-3000
060320
000000
000000
001000
(D)SSSWWWDSSS
000000
000-300
060320
000000
000000
001000
(S)SSWWWDSSS
000000
000000
060-320
000300
000000
001000
(S)SWWWDSSS
000000
000000
060020
000-300
000300
001000
(S)WWWDSSS
000000
000000
060020
000000
000-300
001300
(W)WWDSSS
000000
000000
060020
000-300
000000
001300
(W)WDSSS
000000
000000
060-320
000000
000000
001300
(W)DSSS
000000
000-300
060020
000000
000000
001300
(D)SSS
000000
0000-30
060020
000000
000000
001300
(S)SS
000000
000000
0600-30
000020
000000
001300
(S)S
000000
000000
060000
0000-30
000020
001300
Output state:
(S)
000000
000000
060000
000000
0000-30
001320
cg35_example.txt ASCII text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Input state:
()W
000000
001000
06-3320
000000
000000
000000
Intermediary states:
Output state:
(W)
001000
00-3000
060320
000000
000000
000000

Input state:
()S
000000
001000
06-3320
000000
000000
000000
Intermediary states:
Output state:
(S)
000000
001000
060320
00-3000
000000
000000

Input state:
()A
000000
001000
06-3320
000000
000000
000000
Intermediary states:
Warning: current move A is skipped because of a blocking wall!
Output state:
(A)
000000
001000
06-3320
000000
000000
000000

Input state:
()D
000000
001000
06-3320
000000
000000
000000
Intermediary states:
Output state:
(D)
000000
001000
060-332
000000
000000
000000