14
\$\begingroup\$

Your task is to regulate traffic on a crossroads. There are 4 roads coming from north, east, south and west.

The input is a string representing the upcoming traffic on each road. For example, NNNWS indicates there is a total of 5 cars: three at the north, one at the west and one at the south. The order of characters has no importance here, NNNWS is equivalent to WNNSN.

You must output the order in which the cars should go, using the priority to the right rule: cars coming from the south must let cars coming from east go first, east gives way to north, north gives way to west and west gives way to south.

For example, with the input NNNWS, the south car should go first, then the west car, then the 3 north cars. The output should thus be SWNNN.

There are some indecidable cases, for example NS or NNWSE : you should then output the string stuck.

Test cases

N => N NW => WN NWS => SWN SNW => SWN SSSSS => SSSSS ENNNNES => NNNNEES NS => stuck NNWSE => stuck 
\$\endgroup\$
8
  • 3
    \$\begingroup\$ Both of those seem a lot harder because they take the outgoing directions into account as well. \$\endgroup\$ Commented Sep 30, 2016 at 13:14
  • 3
    \$\begingroup\$ I would recommend using undefined behavior instead of printing stuck. \$\endgroup\$ Commented Sep 30, 2016 at 13:29
  • 6
    \$\begingroup\$ @Erik when dealing with road safety, an undefined behavior cannot be accepted :-) \$\endgroup\$ Commented Sep 30, 2016 at 13:54
  • 2
    \$\begingroup\$ Related. Related. \$\endgroup\$ Commented Sep 30, 2016 at 14:39
  • 2
    \$\begingroup\$ Is the empty string possible as input ? If so, what should the result be? And why is NS stuck ? Because both NS and SN would be a solution ? \$\endgroup\$ Commented Oct 1, 2016 at 6:39

6 Answers 6

2
\$\begingroup\$

Perl, 65 bytes

Includes +2 for -lp

Give input on STDIN. Assumes the empty string is not a valid input

#!/usr/bin/perl -lp s%.%'+(y/NESW/ESWN/*s/N(.*)W/W$1N/,/N/^/S/)'x4%gere+0or$_=stuck 

If you don't mind the absence of a newline after stuck you can drop the l option

\$\endgroup\$
2
\$\begingroup\$

PHP, 267 Bytes

use the new spaceship operator and usort -5 Bytes by @IsmaelMiguel

<?foreach($f=[E,S,W,N]as$l)$s.=+!($r=strstr)($i=$argv[1],$l);if(in_array($s,[0101,1010,0000]))die(stuck);$x=($p=strpos)($s,"1");$t=$r($j=join($f),$f[$x]).$r($j,$f[$x],1);$a=str_split($i);usort($a,function($x,$y)use($t,$p){return$p($t,$x)<=>$p($t,$y);});echo join($a); 

Breakdown

# Extended Version without notices $s=""; foreach($f=["E","S","W","N"] as $l){$s.=+!strstr($i=$argv[1],$l);} #bool concat swap the false true values in string if(in_array($s,["0101","1010","0000"])){die("stuck");} # NS WE NESW -> stuck = end program $x=strpos($s,"1"); # find the first false value for an begin for the sort algorithm $t=strstr($j=join($f),$f[$x]).strstr($j,$f[$x],1); # create the sort pattern #sort algorithm example sort string = NESW-> N is not in the string function c($x,$y){ global $t; return strpos($t,$x)<=>strpos($t,$y); # e.g. comparison E<=>W =-1 , W<=>S=1, W<=>W =0 } $a=str_split($i); # Input in an array usort($a,"c"); #sort array echo join($a);# output array as string 
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Instead of function c($x,$y){global$t,$p;return$p($t,$x)<=>$p($t,$y);}$a=str_split($i);usort($a,c);, you can use $a=str_split($i);usort($a,function($x,$y)use($t,$p){return$p($t,$x)<=>$p($t,$y);}); and save 5 bytes. The spaceship operator really helped with this sort of sorting. For you to understand what I did, I moved the function into usort(), making it an anonymous function. Then, instead of global (NEVER use it), I've used function(...)use($t,$p){...}. The use(...) syntax allows you to pass variables into the anonymous function body (it accepts recerences too). \$\endgroup\$ Commented Oct 2, 2016 at 8:16
  • \$\begingroup\$ @IsmaelMiguel Thank You for this wonderful explaining. \$\endgroup\$ Commented Oct 2, 2016 at 10:10
  • \$\begingroup\$ You're welcome. I really love the use() bit on anonymous functions. You should use and abuse it. \$\endgroup\$ Commented Oct 2, 2016 at 10:12
1
\$\begingroup\$

Batch, 216 bytes

@echo off set/pt= set/an=2,e=4,s=8,w=16,r=0 :l set/ar^|=%t:~0,1% set t=%t:~1% if not "%t%"=="" goto l set/a"o=449778192>>r&3,l=1053417876>>r&3" if %l%==0 (echo stuck)else set t=NESWNE&call echo %%t:~%o%,%l%%% 

Simple port of my JavaScript answer. Takes input on STDIN in upper or lower case.

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 108 107 106 104 bytes

s=>(r=t=`NESWNE`,s.replace(/./g,c=>r|=2<<t.search(c)),t.substr(449778192>>r&3,1053417876>>r&3)||`stuck`) 

Accumulates a bitmask of which directions have approaching cars and extracts the appropriate portion of the priority string.

\$\endgroup\$
5
  • \$\begingroup\$ Uncaught SyntaxError: Invalid regular expression: missing / \$\endgroup\$ Commented Sep 30, 2016 at 18:45
  • \$\begingroup\$ @Cyoce Whoops. What happened was that the browser wrapped the code at that point and I thought a newline had crept in. Sorry about that. \$\endgroup\$ Commented Sep 30, 2016 at 18:48
  • \$\begingroup\$ no problem, just letting you know. \$\endgroup\$ Commented Sep 30, 2016 at 21:57
  • \$\begingroup\$ Each way only 1 car pass? \$\endgroup\$ Commented Nov 7 at 7:21
  • \$\begingroup\$ @l4m2 I have trouble remembering stuff nine minutes ago let alone nine years... I think the idea is that it doesn't matter how many cars there are in a given direction, they all go at the same time anyway, so you only need to know the order of the directions. \$\endgroup\$ Commented Nov 7 at 9:31
0
\$\begingroup\$

Python3, 390 bytes

E=enumerate def f(C): q,r=[(j,[j],['ES','NE','WN','SW'])for j in'NSEW'],[] for a,p,s in q: if[]==s: O=p[1:-1] if all(u in O for u in C): k,F='',1 W=O[min(i for i,a in E(O)if a in C):] c=[*C] while c: if(t:=c.count(w:=W.pop(0))):k+=w*t;c=[i for i in c if i!=w] else:F=0;break if F:return k q+=[(A[1],p+[A[1]],s[:I]+s[I+1:])for I,A in E(s)if A[0]==a] 

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 369 bytes \$\endgroup\$ Commented Nov 8 at 18:41
0
\$\begingroup\$

JavaScript (Node.js), 103 bytes

f=x=>[...x].filter(k=c=>k==c|/^N.*W|^E.*N|^S.*E|^W.*S/.test(c+x)?!(p+=c):k=c,p='')==k?k+f(p):x&&'stuck' 

Try it online!

f = x => // Take x [...x].filter( // Filter the car that k = c => // k initially gibberish k == c | // If not first car in the queue // (Not necessary correct for e.g. NSN // but it doesn't matter) /^N.*W|^E.*N|^S.*E|^W.*S/.test(c + x) ? // Blocked by right side !(p += c) : // Push to blocked k = c, // Let the car go p = '' // blockeds initially empty ) == k ? // If exactly 1 car, in which case // the car must have been stored in k k + f(p) : // Let it go and recurse other cars x && // Cleared, return empty 'stuck' // Not cleared but no/multi car move // Can be proven that stuck can't // happen late 
\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.