11
\$\begingroup\$

Sandbox post here.

Create a function or program that "Springifies" a string.

  • Input will be a String in Stdin, or closest alternative
  • Input will only contain printable ASCII and/or spaces
  • Output will be to Stdout, or closest alternative
  • A trailing newlines and spaces are acceptable

How to springify a String

  1. Format the String into as many ASCII spring coils as needed
  2. Pad the coils with spaces, up to the nearest coil
  3. Read off the characters, following the spring around the coils

This is an ASCII spring coil:

#
# ####
 #    #
# ####
#

Where the #s are the characters of the String

Here is an example:

abcdefghijklmnopqrstuvwxyz

becomes

a
b cdef
 g    h
i jklm
n
o
p qrst
 u    v
w xyz.
.

Where the .s replace spaces for visibility.

Then, the string is read back, following the ASCII spring downwards, around the loops, hitting the g and u twice:

1| a  <-3
 V b cdef
    g    h
4| i jklm
 V n  2->
  ...

...giving:

abgjklmhfedcginopuxyz vtsrquw (with a trailing space)

Test Cases

(quotations added to highlight trailing spaces - please ignore in terms of IO)

I: "abcdefghijklmnopqrstuvwxyz"
O: "abgjklmhfedcginopuxyz vtsrquw "

I: "!@#"
O: "!@         #   "

I: ""
O: ""

I: "12345 67890"
O: "12690  7 54368 "

I: " "
O: "               "

Note that the output length is always a multiple of 15, the length of a spring coil

This is , so the shortest answer in bytes wins.

\$\endgroup\$
  • \$\begingroup\$ I feel like it would've been much more of a challenge to follow the pattern along the coil. \$\endgroup\$ – Magic Octopus Urn Jan 20 '17 at 14:52
  • \$\begingroup\$ @carusocomputing you mean the inverse? \$\endgroup\$ – MildlyMilquetoast Jan 20 '17 at 16:47
  • \$\begingroup\$ codegolf.stackexchange.com/a/107531/59376 turns out I didn't understand the challenge as written, that's exactly the challenge ahaha. \$\endgroup\$ – Magic Octopus Urn Jan 20 '17 at 17:00

11 Answers 11

2
\$\begingroup\$

Jelly, 26 bytes

“4ṘƝ;þ¦Ɱ’b®¤ị
;⁶x14©¤s®ṖÇ€

TryItOnline!

How?

“4ṘƝ;þ¦Ɱ’b®¤ị - Link 1, output for a single coil: char array
           ¤  - nilad followed by link(s) as a nilad
“4ṘƝ;þ¦Ɱ’     - base 250 number, 13140239220751650
          ®   - retrieve from register (14 from main link)
         b    - convert to base, [1,2,7,10,11,12,13,8,6,5,4,3,7,9,0]
            ị - index into the char array

;⁶x14©¤s®ṖÇ€ - Main link: theString
      ¤      - nilad followed by link(s) as a nilad
 ⁶           - a space character
  x          - repeated
   14©       - place 14 into the register and yield 14
;            - concatenate theString with the 14 spaces
       s     - split into chunks of length
        ®    -     retrieve from register (14)
         Ṗ   - pop last entry from the result (removes the space only last entry of 14 chars or less)
          Ç€ - call the last link (1) as a monad for €ach
             - implicit print
| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

Python 2, 104 102 98 Bytes

f=lambda t:''.join((t+' '*13)[ord(x)-97+y*14]for y in range(len(t)/14+1)for x in'abgjklmhfedcgin')

Thanks for the comment help!

https://tio.run/#2VDVy

Original:

t=raw_input()+' '*13
print''.join(t[ord(x)-97+y*14]for y in range(len(t)/14)for x in'abgjklmhfedcgin')
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can just use input() and take input in the format "<stuff>". \$\endgroup\$ – HyperNeutrino Jan 20 '17 at 3:24
  • \$\begingroup\$ Great first golf! As Alex L. points out, we allow input to be taken in quotes. You can also use a lambda to give an anonymous function rather than a program -- this is often shorter. \$\endgroup\$ – xnor Jan 20 '17 at 3:28
  • \$\begingroup\$ Fails for the empty string test case with an IndexError. I think you may need to change 13 to 14 and pop off the final value (much like my Jelly answer). \$\endgroup\$ – Jonathan Allan Jan 20 '17 at 7:30
  • \$\begingroup\$ ...changing the +13 to +14 and the +1 to +(len(t)%14>0) would do it, but there must be a shorter way. \$\endgroup\$ – Jonathan Allan Jan 20 '17 at 7:41
3
\$\begingroup\$

JavaScript (ES6), 79 bytes

f=
s=>s.replace(/.{1,14}/g,s=>'0169abc7543268d'.replace(/./g,c=>s['0x'+c-0]||' '))
<input oninput=o.textContent=f(this.value)><pre id=o>

Hexadecimal string shamelessly stolen from @ETHproductions.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ @ETHproductions Thanks, fixed. \$\endgroup\$ – Neil Jan 20 '17 at 17:04
  • \$\begingroup\$ That's brilliant! \$\endgroup\$ – dodov Jan 20 '17 at 22:11
  • \$\begingroup\$ It's nice how the snippet lets you see the result as you type it \$\endgroup\$ – MildlyMilquetoast Jan 22 '17 at 19:26
2
\$\begingroup\$

Retina, 71 bytes

$
13$* 
M!`.{14}|$
(.)(.)(.)(.)(.)(.)(.)(....)(.)¶
$5$8$6$4$3$2$1$5$7$9

Try it online!

Permuting strings isn't exactly concise in Retina...

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES7), 144 143 141 114 104 103 bytes

Thanks to ETHProductions for a 10B save!

a=>[...b=a+' '.repeat(15-a.length%15)].map((_,c)=>b['0x'+'0169abc7543268d'[c%15]-0+(c/15|0)*14]).join``

Example

f=a=>[...b=a+' '.repeat(15-a.length%15)].map((_,c)=>b['0x'+'0169abc7543268d'[c%15]-0+(c/15|0)*14]).join``
f('abcdefghijklmnopqrstuvwxyz')

Output

abgjklmhfedcginopuxyz vtsrquw 
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Very nice. You can save some bytes by converting the array to a hexadecimal string, and using +('0x'+whatever) to convert it to a number: (_,c)=>b[(c/15|0)*14+ +('0x'+'0169abc7543268d'[c%15])] \$\endgroup\$ – ETHproductions Jan 20 '17 at 12:45
  • \$\begingroup\$ Clever trick. I was already thinking of other ways to write the array, but I couldn't come up with any. I can still shorten that, by placing the hexadecimal number first and then the multiplication, making the space needless. \$\endgroup\$ – Luke Jan 20 '17 at 14:22
  • \$\begingroup\$ You could even do '0x'+'...'[c%15]-0+(c/15|0)*14 to save yourself a pair of parentheses :-) \$\endgroup\$ – ETHproductions Jan 20 '17 at 14:32
  • \$\begingroup\$ You're right. Added. \$\endgroup\$ – Luke Jan 20 '17 at 14:40
2
\$\begingroup\$

Perl 6, 61 bytes

{S:g/(.)**1..14/{[~] $0["abgjklmhfedcgin".ords X-97]X//" "}/}

How it works

The basic structure is this:

{                                  }  # A lambda.
 S:g/(.)**1..14/{                }/   # Regex-replace segments of 1-14 characters, with:
                     $0               #   The single-char submatches captured by the parens.
                       [  ]           #   Index them using certain indices (see below).
                           X//" "}    #   Replace each undefined element with a space.
                 [~]                  #   Concatenate the characters.

The expression used to index into each 14-characters segment is "abgjklmhfedcgin".ords X- 97, which works as follows:

  1. Take the hard-coded string abgjklmhfedcgin.
  2. Get its codepoints: 97 98 103 106 107 108 109 104 102 101 100 99 103 105 110.
  3. Subtract 97 from each number: 0 1 6 9 10 11 12 7 5 4 3 2 6 8 13.

Perl 6, 64 bytes

{[~] .comb(14)».comb»[0,1,6,9..12,7,5...2,6,8,13].flat X//" "}

Try it online!

How it works

The basic structure is this:

{                                    }  # A lambda.
     .comb(14)                          # Split the argument into substrings of <= 14 chars.
              ».comb                    # Split each substring into a list of characters.
                    »[  ]               # Index each list using the same indices (see below).
                         .flat          # Flatten the resulting nested list.
                               X//" "   # Replace each undefined element with a space.
 [~]                                    # Concatenate the list to get a string again.

Same indices as above, but since we're calling .flat anyway, we can use a nested (but 1 byte shorter) expression for them: 0,1,6,9..12,7,5...2,6,8,13.

(Looks trivial, but actually relies on a parsing peculiarity of Rakudo Perl 6 that is probably a bug. To write it without exploiting that bug, one would have to add parens around the 5...2.)

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Befunge-93, 97 bytes

<>0>v%2g3\p89:-1+*"!"!:+1<_@#`0:~
,^\,_\:98g\9p1+:76+`#v_:~^
^,,g96g98g9+67,,,,,$$_
==    =  ====

Try it online!

This is a breakdown of the source code with the various component parts highlighted.

Source code with execution paths highlighted

* The main loop starts off executing right to left, wrapping around to the right hand side of the playfield. This is where we read the first character from stdin, and terminate if it's an EOF.
* The next section makes sure any EOF characters are converted to spaces using the formula c = c + 31*!(c+1). Although this won't apply on the first iteration, it can occur on subsequent passes.
* A copy of the character is saved to temporary memory, and then a lookup of the current index is performed on the table on line four (*) to determine whether the character should be output or not.
* If the character needs to be output, we take the left branch. A swap is performed here to cancel out the swap that's going to occur next, and then a zero is pushed to force the branch right.
* If the character wasn't output, we swap it down the stack beneath the index counter (this is the swap that gets cancelled in the left branch). And in both cases we save the character to memory at the current index offset, increment the index, and check if it's greater than 13.
* If not, we read the next character from stdin and repeat the inner loop.
* If it is, we'll have finished a set of 14 characters, 7 having been output (abgjklm), and 7 remaining on the stack (cdefhin). We drop the last two, output the remaining 5 (hfedc), and then retrieve and output the special cases g, i and n from memory.
* And that brings us back to the start of the main loop, where we repeat the process again for the next 14 characters.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Nice explanation, well done \$\endgroup\$ – MildlyMilquetoast Jan 22 '17 at 19:26
1
\$\begingroup\$

Mathematica, 77 72 bytes

Thanks to JungHwan Min for saving 5 bytes!

Join@@Partition[#,14,14,{1,1}," "][[;;,LetterNumber@"abgjklmhfedcgin"]]&

Unnamed function taking a list of characters as input and returning a list of characters. Partition[#,14,14,{1,1}," "] splits the input into sublists of length 14, padding with spaces if necessary. LetterNumber@"abgjklmhfedcgin" evaluates to {1,2,7,10,11,12,13,8,6,5,4,3,7,9,14}, which indicates the order to take each length-14 sublist in (repeating the 7th element appropriately). Then [[;;,...]] takes the elements of all the length-14 sublists in that order, and Join@@ joins the answers together.

Previous submission:

Join@@Partition[#,14,14,{1,1}," "][[All,83224017339955102~IntegerDigits~16]]&
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ LetterNumber@"abgjklmhfedcgin" is a shorter way to compress the list. Also ;; instead of All saves a byte. \$\endgroup\$ – JungHwan Min Jan 20 '17 at 4:33
  • \$\begingroup\$ Great suggestions! \$\endgroup\$ – Greg Martin Jan 20 '17 at 4:41
1
\$\begingroup\$

Python 3, 86 bytes

lambda s:''.join(t[i%14]for t in zip(*[iter(s+' '*13)]*14)for i in b'Tq>]zQ|1/X;:L$o')

Try it online!

As a bonus, the string Tq>]zQ|1/X;:L$o is a valid CJam program that prints the unique characters on standard input, sorted. Try it online! (+ explanation)

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

PHP, 94 bytes

foreach(str_split($argv[1],14)as$s)for($i=0;$c=abgjklmhfedcgin[$i++];)echo$s[ord($c)-97]??" ";

splits command line argument to 14-byte chunks and loops through the translation string as index for the sub-string. Run with php -nr '<code>' <string>.

I was glad to find out that ?? also accepts the empty string (for an "invalid" index) as null.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Ruby, 83 bytes

->s{v="";(s+" "*13).scan(/.{14}/){|y|"0169:;<7543268=".chars{|o|v+=y[o.ord-48]}};v}

First idea was using hex numbers, but ord-48 saves another byte (stolen from throx's answer).

| improve this answer | |
\$\endgroup\$

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.