12
\$\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\$
  • 3
    \$\begingroup\$ Both of those seem a lot harder because they take the outgoing directions into account as well. \$\endgroup\$ – Martin Ender Sep 30 '16 at 13:14
  • 3
    \$\begingroup\$ I would recommend using undefined behavior instead of printing stuck. \$\endgroup\$ – Erik the Outgolfer Sep 30 '16 at 13:29
  • 4
    \$\begingroup\$ @Erik when dealing with road safety, an undefined behavior cannot be accepted :-) \$\endgroup\$ – Arnaud Sep 30 '16 at 13:54
  • 2
    \$\begingroup\$ Related. Related. \$\endgroup\$ – Fatalize Sep 30 '16 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\$ – Ton Hospel Oct 1 '16 at 6:39
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\$
  • 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\$ – Ismael Miguel Oct 2 '16 at 8:16
  • \$\begingroup\$ @IsmaelMiguel Thank You for this wonderful explaining. \$\endgroup\$ – Jörg Hülsermann Oct 2 '16 at 10:10
  • \$\begingroup\$ You're welcome. I really love the use() bit on anonymous functions. You should use and abuse it. \$\endgroup\$ – Ismael Miguel Oct 2 '16 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\$
  • \$\begingroup\$ Uncaught SyntaxError: Invalid regular expression: missing / \$\endgroup\$ – Cyoce Sep 30 '16 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\$ – Neil Sep 30 '16 at 18:48
  • \$\begingroup\$ no problem, just letting you know. \$\endgroup\$ – Cyoce Sep 30 '16 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.