Wave-Particle Duality Laterally Programmatically

30

3

Write a program or function that takes in a nonempty single-line string. The string will either be zero or more spaces followed by one period (a particle), such as . or          ., or the string will be a sequence of one or more alternating forward and back slashes (a wave) that could start with either one, such as \ or /\/ or \/\/\/\/\/\/.

In either case, propagate the particle/wave to the right by one unit.

Specifically, in the particle case, insert a space before the ., moving it one place to the right, then output the resulting string. For example:

. .
 .  .
  .   .
   .    .
    .     .
     .      .
      .       .
       .        .

In the wave case, append either / or \ appropriately so the wave keeps alternating and it's length increases by one, then output the resulting string. For example:

//\
\\/
/\/\/
\/\/\
/\//\/\
\/\\/\/
/\/\/\/\/
\/\/\/\/\

In either case, the output may not have trailing spaces but an optional trailing newline is allowed.

The shortest code in bytes wins.

Calvin's Hobbies

Posted 2016-08-14T00:54:01.683

Reputation: 84 000

Comments are not for extended discussion; this conversation has been moved to chat.

– Dennis – 2016-08-14T03:33:33.413

Answers

16

C, 69 bytes

p;f(char*s){p=s[strlen(s)-1]^46;p^=p?93:3022856;printf("%s%s",s,&p);}

This requires a little-endian machine, and output to a terminal that support ASCII escape codes.

p=s[strlen(s)-1]^46 grabs the last ASCII code of the input string, and XORs it with the ASCII code of a dot.

p^=p?93:3022856 will cause p to be p^93 if the ASCII code is not a (back)slash, where p^46^93 == p^115, which will toggle between back and forward slash. If p is a dot, it will instead be 3022856, which is little-endian for "\b .".

printf("%s%s",s,&p); prints the input string followed by the integer p, interpreted as a little-endian byte string.

orlp

Posted 2016-08-14T00:54:01.683

Reputation: 37 067

1This is pure genius. – Leaky Nun – 2016-08-14T06:22:00.177

You can save one byte by replacing 3022856 with '. \b', a multibyte character literal. Awesome answer ! – Quentin – 2016-08-15T10:09:03.837

Could anyone come up with a version of this that doesn't use any stdlib stuff? :) – TylerY86 – 2016-09-26T02:52:51.687

12

Jelly, 17 14 bytes

ṪO*2.ị“ .\/\”ṭ

Try it online! or verify all test cases.

How it works

ṪO*2.ị“ .\/\”ṭ  Main link. Argument: s (string)

Ṫ               Tail; pop and yield the last character.
 O              Ordinal; map “./\” to [46, 47, 92].
  *2.           Elevate the code point to the power 2.5.
                This maps [46, 47, 92] to [14351.41, 15144.14, 81183.84].
     ị“ .\/\”   Index into that string.
                Jelly's indexing is modular, so this takes the indices modulo 5,
                which gives [1.41, 4.14, 3.84].
                Also, for a non-integer index, ị retrieves the elements at both
                adjacent integer indices (1-based). Here, these are [1, 2], [4, 5],
                and [3, 4], so we get " .", "/\", or "\/".
             ṭ  Tack; append the characters to the popped input string.

Dennis

Posted 2016-08-14T00:54:01.683

Reputation: 196 637

Huh. Just realised this is 22 bytes in UTF-8. Wonder if other code pages can be used to reduce the byte count of other prorams. – TylerY86 – 2019-12-07T01:49:34.067

7

CJam, 16 bytes

l)_'.={S\}"\/"?|

Try it online! or verify all test cases.

How it works

l                 Read a line from STDIN.
 )_               Shift out the last character and copy it.
   '.=            Compare the copy with a dot.
              ?   If the last character is a dot:
      {S\}            Push " " and swap the dot on top.
          "\/"    Else, push "\/".
               |  Perform set union, ordering by first occurrence.
                    " " '.  | -> " ."
                    '/ "\/" | -> "/\"
                    '\ "\/" | -> "\/"

Dennis

Posted 2016-08-14T00:54:01.683

Reputation: 196 637

1Note to self: learn how set union works. This seems to be where most of the bytes were saved when compared to mine. – Zwei – 2016-08-14T15:56:45.163

6

Python, 41 bytes

lambda s:[s+'\/'[s[-1]>'/'],' '+s][s<'/']

Casework. Uses the sorted order ' ', '.', '/', '\'. For spaces and period, prepends a space. Otherwise, appends a slash or blackslash opposite to the last character.

xnor

Posted 2016-08-14T00:54:01.683

Reputation: 115 687

5

Python, ​ 44 ​ ​42 bytes

lambda s:s[:-1]+"\/ /\."[-ord(s[-1])&3::3]

Replaces the last character with the correspond set of two characters. ideone link

(-2 bytes thanks to @xsot's shorter mapping function)

Sp3000

Posted 2016-08-14T00:54:01.683

Reputation: 58 729

-ord(s[-1])&3 also gives 3 different indices. – xsot – 2016-08-14T02:05:57.013

@xsot Oh nice, I didn't think of &! – Sp3000 – 2016-08-14T02:10:40.490

No meme this time? :'( – ThreeFx – 2016-09-03T19:55:35.453

5

Game Maker Language, 107 bytes

s=argument0;if string_pos(" ",s)return " "+s;if string_pos(s,string_length(s))="/"s+="\"else s+="/"return s

Timtech

Posted 2016-08-14T00:54:01.683

Reputation: 12 038

5

Vim, 27 23 keystrokes

First vim answer ever, haven't used vim at all really even.

A/<esc>:s#//#/\\<cr>:s#\./# .<cr>

How it works: It appends a / at the end of line, subs // for /\, subs ./ for .

Destructible Lemon

Posted 2016-08-14T00:54:01.683

Reputation: 5 908

You can avoid escaping the /s if you use a different delimiter, for example s#//#/\\. – m-chrzan – 2016-08-17T03:42:30.180

Thanks, I had no idea anything like that existed – Destructible Lemon – 2016-08-17T03:48:39.860

4

MATL, 19 bytes

t47<?0w}'\/'yO)o)]h

Try it online! Or verify all test cases.

Explanation

t        % Input string implicitly. Duplicate
47<      % Are entries less than 47 (i.e dot or spaces)?
?        % If all are
  0      %   Push a 0. When converted to char it will be treated as a space
  w      %   Swap, so that when concatenated the space will be at the beginning
}        % Else
  '\/'   %   Push this string
  y      %   Duplicate the input string onto the top of the stack
  O)     %   Get its last element
  o      %   Convert to number    
  )      %   Use as (modular) index to extract the appropripate entry from '\/'
]        % End
h        % Concatenate string with either leading 0 (converted to char) or
         % trailing '\'  or '/'. Implicitly display

Luis Mendo

Posted 2016-08-14T00:54:01.683

Reputation: 87 464

3

CJam, 35 26 25 bytes

Saved 9 bytes thanks to dennis

Saved 1 more byte, also thanks to dennis

q:I'.&SI+IW='/=I'\+I'/+??

Try it online!

Probably poorly golfed, but I'm not too familiar with CJam. There's probably a better way to check if an element is in an array, but I couldn't find any operators for that.

Explanation:

q:I e# take input
'.& e# push union of input and ".", effectively checking if input contains it
SI+ e# push string with space in beginning
IW='/= e# push 1 if the last chsaracter in the input is /
I'\+ e# push the input with a \ appended
I'/+ e# push the input with a / appended
? e# ternary if to select correct /
? e# ternary if to select final result

Zwei

Posted 2016-08-14T00:54:01.683

Reputation: 484

1W is initially -1 and ? works both with blocks and other stack items, so you can reduce your code to q:I'.#)SI+IW='/=I'\+I'/+?? – Dennis – 2016-08-14T20:30:23.580

1To test if a character belongs to a string, you can intersect them with &. – Dennis – 2016-08-14T23:44:57.170

I am so bad at CJam lol – Zwei – 2016-08-15T02:17:41.910

3

05AB1E, 17 15 bytes

D'.åiðì뤄\/s-J

Explanation

D'.åi              # if input contains dot
     ðì            # prepend a space
       ë           # else
        ¤„\/s-     # subtract last char of input from "\/"
              J    # join remainder to input
                   # implicitly print

Try it online

Emigna

Posted 2016-08-14T00:54:01.683

Reputation: 50 798

2

C, 85 bytes

j;f(char*n){j=strlen(n)-1;printf("%s%s",n[j]<47?" ":n,n[j]==46?n:n[j]==47?"\\":"/");}

Ideone

I haven't slept for about 20 hours, my code probably can be golfed a lot.

betseg

Posted 2016-08-14T00:54:01.683

Reputation: 8 493

2

Brachylog, 35 bytes

t~m["\/.":X]t:"/\ "rm:?{.h" "|r.}c.

Test suite. (Slightly modified.)

Leaky Nun

Posted 2016-08-14T00:54:01.683

Reputation: 45 011

2

Retina, 19 bytes

\.
 .
/$
/\^H
\\$
\/

^H represents the BS byte. Try it online!

Dennis

Posted 2016-08-14T00:54:01.683

Reputation: 196 637

Why the backspace character? – Robert Fraser – 2016-08-14T19:55:54.707

Without it, the next replacement would match the trailing backslash. For example, input / would become /\/. – Dennis – 2016-08-14T19:58:44.957

2

Matlab, 74 71 62 57 bytes

@(s)[s(1:end-1) ' .'+(s(1)>46)*'/.'+(s(end)>47)*[45 -45]]

It computes the last two characters based on the s(1) (first character) - to determine if we're dealing with the \/ case, and the last character s(end) to make the correct tuple for the \/ characters.

pajonk

Posted 2016-08-14T00:54:01.683

Reputation: 2 480

2

JavaScript, 79 70 65 58 bytes

(a,b="/\\/",i=b.indexOf(a[a.length-1]))=>i<0?" "+a:a+b[i+1]

kamoroso94

Posted 2016-08-14T00:54:01.683

Reputation: 739

1Replace b.charAt(i+1) with b[i+1] to save some bytes. Also, this does not work for all test cases. \/ gives /\\, for example. – user2428118 – 2016-08-15T13:42:27.230

@user2428118 Thanks, bug fixed and code shortened! – kamoroso94 – 2016-08-15T14:02:48.690

1init b and i as params with a default value: (a,b=...,i=...)=> to avoid return – charlie – 2016-08-15T14:35:09.293

Ah yes, I forgot about that new feature. Also was able to remove the { } as well because of this. – kamoroso94 – 2016-08-15T14:45:17.653

in fact, with a few more steps, you'll converge to the answer of @TylerY86 – charlie – 2016-08-15T15:06:55.317

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Specifications

Can't use arrow methods in "JavaScript" until the living standard defers to ECMAScript 2015, instead of ECMAScript 5.1. It might not matter for this case. :)

– TylerY86 – 2016-08-15T15:42:42.390

2

><>, 47 bytes

i:0(?\
*=?$r\~:1[:"./ \/"{=?@r=?$r~~]:48
l?!;o>

Try it online!

The first line is a standard ><> input loop. The second line chooses the appropriate character from / \ to append to the string, based on the last input character. In addition, if the last input character was a ., the top two elements are switched. Finally, the stack contents are printed in reverse.

Sok

Posted 2016-08-14T00:54:01.683

Reputation: 5 592

2

C# - 46 bytes

s=>s[0]<47?' '+s:s+(s.EndsWith("/")?'\\':'/')

Try it here.

TylerY86

Posted 2016-08-14T00:54:01.683

Reputation: 131

2

Haskell, 46 45 44 bytes

f z@(x:_)|x<'/'=' ':z|x<'0'='\\':z|1<2='/':z

Takes advantage of the fact that < . < / < 0 < \ in the ASCII table to save two bytes

BlackCap

Posted 2016-08-14T00:54:01.683

Reputation: 3 576

1

ECMAScript 6 / 2015 (JavaScript), 41 bytes

s=>s<'/'?' '+s:s+'\\/'[s.slice(-1)>'/'|0]

Good catch Neil.

TylerY86

Posted 2016-08-14T00:54:01.683

Reputation: 131

Your output seems to be incorrect. For the slashes, your code should append the next slash, not prepend it. – Dennis – 2016-08-14T07:49:32.650

Adjusted answer. – TylerY86 – 2016-08-14T08:20:11.147

Why not +(s+1)? – Neil – 2016-08-14T09:55:55.657

Better still, s<'/'. – Neil – 2016-08-14T10:07:50.423

1

Python 2, 72 bytes

lambda x:x[:-1]+(" .","\/","/\\")[ord(x[-1])/46+(-1,1)[ord(x[-1])%46>0]]

Any help golfing more would be greatly appreciated!

This takes the last character in the input and converts it into its ASCII code to get the corresponding index in the list of two characters. Those two characters are appended to all the characters of the input up until the last one.

Daniel

Posted 2016-08-14T00:54:01.683

Reputation: 6 425

1

C#, 80 63 bytes

s=>{var c=s[s.Length-1];retu‌​rn c<'/'?" "+s:c>'/'?s+"/":s+"\\‌​";}

downrep_nation

Posted 2016-08-14T00:54:01.683

Reputation: 1 152

Can you get it to work using a lambda expression? – TylerY86 – 2016-08-14T17:09:40.777

s=>{var c=s[s.Length-1];return c<'/'?" "+s:c>'/'?s+"/":s+"\\";} 63 https://dotnetfiddle.net/8x79az – TylerY86 – 2016-08-14T17:22:56.833

s=>{var c=s[s.Length-1];return c<47?' '+s:s+(c>47?'/':'\\');} 61 https://dotnetfiddle.net/ykKIL1 – TylerY86 – 2016-09-03T19:17:18.730

Added a 46 byte competitor for you. :) – TylerY86 – 2016-09-03T19:28:21.997

1

Perl, 30 + 1 (-p) = 31 bytes

s/\./ ./,s|/$|/\\|||s|\\$|\\/|

Needs -p and -M5.010 or -E to run :

perl -pE 's/\./ ./,s|/$|/\\|||s|\\$|\\/|' <<< ".
  .
    .
/
/\/" 

Straight forward implementation of the challenge. (Note that the || between the last two regex are or, as it might be hard to read, so the three regex are : s/\./ ./, and s|/$|/\\|, and s|\\$|\\/|)

Dada

Posted 2016-08-14T00:54:01.683

Reputation: 8 279

1

SQF, 91

Using the function-as-a-file format:

s=_this;switch(s select[(count s)-1])do{case".":{" "+s};case"\":{s+"/"};case"/":{s+"\"};}

Call as "STRING" call NAME_OF_COMPILED_FUNCTION

Οurous

Posted 2016-08-14T00:54:01.683

Reputation: 7 916

1

PowerShell v2+, 59 58 52 51 bytes

param($n)(" $n","$n/","$n\")['.\/'.IndexOf($n[-1])]

Takes input $n, dumps it an array index operation. We select the element of the array based on the index ['.\/'.IndexOf($n[-1]) -- i.e., based on the last character of the input $n, this will result in 0, 1, or 2. That corresponds to the appropriate string of the array. In any case, the resulting string is left on the pipeline and printing is implicit.

Test cases

PS C:\Tools\Scripts\golfing> 0..7|%{' '*$_+'.'}|%{"$_ => "+(.\wave-particle-duality.ps1 "$_")}
. =>  .
 . =>   .
  . =>    .
   . =>     .
    . =>      .
     . =>       .
      . =>        .
       . =>         .

PS C:\Tools\Scripts\golfing> '/,\,/\,\/,/\/,\/\,/\/\,\/\/'-split','|%{"$_ => "+(.\wave-particle-duality.ps1 "$_")}
/ => /\
\ => \/
/\ => /\/
\/ => \/\
/\/ => /\/\
\/\ => \/\/
/\/\ => /\/\/
\/\/ => \/\/\

AdmBorkBork

Posted 2016-08-14T00:54:01.683

Reputation: 41 581

1

C#, 54 bytes

s=>s.EndsWith(".")?" "+s:s+(s.EndsWith("/")?"\\":"/");

TheLethalCoder

Posted 2016-08-14T00:54:01.683

Reputation: 6 930

Provided a 46 byte competitor for you. :) – TylerY86 – 2016-09-03T19:23:47.327

1

SED, 41 36 27

saved 7 thanks to charlie

 s|\.| .|;s|/$|/\\|;t;s|$|/|

uses 3 substitutions:
s/\./ ./ adds a space if there is a .
s|/$|/\\|,s|$|/| adds the appropriate slash to the end
uses | instead of / as the delimiter

t branches to the end if the second regex matches so it doesn't add the other slash

Riley

Posted 2016-08-14T00:54:01.683

Reputation: 11 345

I just came to an almost identical solution: s/\./ ./;s./$./\\.;t;s.$./. -- it's 27 bytes. The 3rd substitution is simplified and on my system the -re is not needed. Also, I use . instead of # to stay visually in the input space. ;o) – charlie – 2016-08-16T09:50:05.210

1

ARM machine code on Linux, 50 bytes

Hex dump:

b580 1e41 f811 2f01 2a00 d1fb 3901 780b 1a0a 4601 2001 2704 df00 2000 a103 2202 f013 0303 2b03 4159 df00 bd80 2e202f5c 5c2f

First post here, hope I'm doing this right. This is 32-bit ARM assembly, specifically Thumb-2. The input string is a NUL-terminated string taken in through r0, the output is printed to the stdout. In C-syntax, the prototype for the function would be void func_name(char* string). It is AAPCS (ARM calling convention) complaint, if it weren't then 2 bytes could be shaved off.

Here's the equivalent assembly, with comments explaining what's happening:

    @Input: r0 is char* (the string)
    @Output: Modified string to console
    push {r7,lr} @Save r7 and the link register
    subs r1,r0,#1 @Make a copy of the char*, subtracting because we're
    @going to pre-increment.
    loop: @This loop is a little strlen routine
            ldrb r2,[r1,#1]! @In C-syntax, r2=*++r1;
            cmp r2,#0
            bne loop
    @Now r1 points to the null character that terminates the string
    subs r1,r1,#1 @Make r1 point to the last character
    ldrb r3,[r1] @Load the last character into r3
    subs r2,r1,r0 @r2=length(r0) - 1;
    mov  r1,r0 @r0 holds the original char*
    movs r0,#1 @1 is the file descriptor for stdout
    movs r7,#4 @4 is write
    swi #0

    @Now all the characters from the initial string have been printed,
    @except for the last one, which is currently in r3.

    movs r0,#1 @1 is stdout, have to reload this since the system call
    @returns in r0.
    adr r1,msg @Load msg into r1 (the pointer to the string)
    movs r2,#2 @We're going to print two more characters.

    @Now the bit magic. The ascii codes for '\', '.', and '/' map onto
    @0, 2, and 3 when bitwise anded with 3 (0b11).
    @This will be the offset into our string. However, since we must print
    @2 characters, we need our offsets to be 0, 2, and 4.
    @Therefore, we only set the carry if our value is >=3, then add with
    @carry (adcs). Thus we get the correct offset into the string msg.
    ands r3,r3,#3
    cmp r3,#3 @Sets carry if r3>=3
    adcs r1,r1,r3 @Add the offset to r1
    swi #0 @Make the system call
    pop {r7,pc} @Return and restore r7
msg:
    .ascii "\\/ ./\\" @The three different sequences of 2 characters that
    @can go at the end.

Ian Chew

Posted 2016-08-14T00:54:01.683

Reputation: 171

1

R, 119 bytes

a=scan(,"");if((q=strsplit(a,"")[[1]][nchar(a)])=="."){cat(" ",a,sep="")}else{s=switch(q,"/"="\\","/");cat(a,s,sep="")}

Ungolfed :

a=scan(,"")
if((q=strsplit(a,"")[[1]][nchar(a)])==".")
    cat(" ",a,sep="")

else
s=switch(q,"/"="\\","/")
cat(a,s,sep="")

Frédéric

Posted 2016-08-14T00:54:01.683

Reputation: 2 059

1

Turtlèd, 32 bytes (noncompeting)

l!-[*+.r_]l(/r'\r)(\r'/)(." .")$

Explanation:

[implicit]                       first cell is an asterisk

l                                move left, off the asterisk, so the '[*+.r_]' loop runs
 !                               take input into string var, char pointer=0, 1st char
  -                              decrement char pointer, mod length input             

   [*    ]                       while current cell isn't *:
     +.                          increment string pointer, and write the pointed char
       r_                        move right, write * if pointed char is last char, else " "

          l                      move left

           (/    )               if the current cell is /
             r'\r                move right, write /, move right

                  (\   )         If the current cell is \
                    r'/          move right, write /

                        (.    )  If the current cell is .
                          " ."   Write " .", the first space overwriting the existing '.'

                               $ Program won't remove leading spaces when printing

    [implicit]                   Program prints grid after finishing execution

Destructible Lemon

Posted 2016-08-14T00:54:01.683

Reputation: 5 908

1

Java 7, 76 bytes

String c(String i){return i.contains(".")?" "+i:i+(i.endsWith("/")?92:'/');}

Pretty straightforward.

Ungolfed & test code:

Try it here.

class M{
  static String c(String i){
    return i.contains(".")
            ? " " + i
            : i + (i.endsWith("/")
                    ? 92
                    : '/');
  }

  public static void main(String[] a){
    System.out.println(c(" ."));
    System.out.println(c("  ."));
    System.out.println(c("   ."));
    System.out.println(c("    ."));
    System.out.println(c("     ."));
    System.out.println(c("      ."));
    System.out.println(c("       ."));
    System.out.println(c("        ."));
    System.out.println(c("/"));
    System.out.println(c("\\"));
    System.out.println(c("/\\"));
    System.out.println(c("\\/"));
    System.out.println(c("/\\/"));
    System.out.println(c("\\/\\"));
    System.out.println(c("/\\/\\"));
    System.out.println(c("\\/\\/"));
  }
}

Output:

  .
   .
    .
     .
      .
       .
        .
         .
/\
\/
/\/
\/\
/\/\
\/\/
/\/\/
\/\/\

Kevin Cruijssen

Posted 2016-08-14T00:54:01.683

Reputation: 67 575

0

Pyth - 16 bytes

?}\.Q+dQ+Q-"\/"e

Test Suite.

Maltysen

Posted 2016-08-14T00:54:01.683

Reputation: 25 023

0

Javascript: 60 bytes

 i=>i.includes(".")?" "+i:i.charAt(i.length-1)=="/"?i+"\\":i+"/"

Dylan Meeus

Posted 2016-08-14T00:54:01.683

Reputation: 220