19
\$\begingroup\$

Challenge

Ever seen those movie trailer titles (namely Martian, Interstellar, etc) where they have huge gaps in between letters slowly spreading out?

The challenge is to recreate this effect given a string, gap multiplier and direction, by inserting appropriate amount of spaces in between the letters.

Example

Input: 'INTERSTELLAR', Gap multiplier: 1.0, Direction: Increasing Inward

Output: I N  T   E    R     S      T     E    L   L  A R

The spacing is: [1, 2, 3, ... , 3, 2, 1]; replacing the spaces with '.' to better demonstrate the spacing:

I.N..T...E....R.....S......T.....E....L...L..A.R

Input: 'INTERSTELLAR', Gap multiplier: 0.5, Direction: Increasing Inward

Output: IN T E  R  S   T  E  L L AR

The spacing is multiplied by 0.5, therefore we get [0, 1, 1, 2, ... 2, 1, 1, 0] from integer division; using '.':

IN.T.E..R..S...T..E..L.L.AR

Input: 'CODEGOLF', Gap multiplier: 2.0, Direction: Increasing Outward

Output: C        O      D    E  G    O      L        F

The spacing is multiplied by 2, increasing outward, therefore we get [8,6,4,2,4,6,8]; replacing with '.':

C........O......D....E..G....O......L........F

Input: 'CODEGOLF', Gap multiplier: 0.4, Direction: Increasing Outward

Output: C O DEGO L F

The spacing is multiplied by 0.4, increasing outward, therefore we get [1,1,0,0,0,1,1]; replacing with '.':

C.O.DEGO.L.F

Rules

  • Takes 3 input: string, gap multiplier and direction
  • If input string is odd in length (even in # of gaps) e.g. 'HELLO', the spacing of the inner most 2 gaps should be the same H E L L O
  • The direction and gap multiplier can be parsed however you want, e.g. you could use -2 as 'increasing inward with a multiplier of 2', 1 as 'increasing outward with a multiplier of 1', etc.
  • It is only required to use spaces, however it is a bonus if the character filling is customizable.

Reference Animation

reference gif

Have fun golfing!

\$\endgroup\$
  • 1
    \$\begingroup\$ Hello, and welcome to PPCG! You might want to make this a bit simpler by changing Increasing to 1 => Inward, 0 => Outward or vice versa. \$\endgroup\$ – NoOneIsHere Oct 6 '16 at 23:31
  • 1
    \$\begingroup\$ @NoOneIsHere Thanks! The direction and ratio parsing is flexible, as per rule 3, you can use 0,1 to specifiy direction or even combining both parameters into one, like +4 for 4 inward, -0.5 for 0.5 outward etc, it just needs to be defined with the solution. \$\endgroup\$ – Zukaberg Oct 6 '16 at 23:36
  • 3
    \$\begingroup\$ This is a very interesting challenge! Welcome to the site. :) \$\endgroup\$ – DJMcMayhem Oct 6 '16 at 23:45
  • \$\begingroup\$ I don't see why a gap ratio of 2 is interpreted as growing outward, while 1 and 0.5 both grow inwards. \$\endgroup\$ – xnor Oct 7 '16 at 1:44
  • \$\begingroup\$ @xnor oh no sorry for the confusion, the direction has nothing to do with the ratio, the direction and ratio are separate parameters, a 2.0 inward would look like: C..O....D......E........G......O....L..F \$\endgroup\$ – Zukaberg Oct 7 '16 at 1:49
3
\$\begingroup\$

JavaScript (ES6), 86 82 81 80 bytes

Input is expected in currying syntax f(s)(r), with:

  • s = string
  • r = ratio + direction: a negative float for inward or a positive float for outward

let f =

s=>r=>s.replace(/./g,(c,i)=>c+' '.repeat(n+=i<l?-r:r),l=s.length/2,n=r>0&&l*r+r)

console.log(f("INTERSTELLAR")(-1));
console.log(f("INTERSTELLAR")(-0.5));
console.log(f("CODEGOLF")(2));
console.log(f("CODEGOLF")(0.4));

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

05AB1E, 33 bytes

Uses CP-1252 encoding.

Gap multiplier is taken as negative when outwards increasing.

g;>Î.S<_²**ÄU¹vyð²¹g<;N.S*X+DUï×J

Try it online!

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

APL, 40 bytes

{⍵\⍨0~⍨∊1,⍨1,¨-⌊⍺×(1+⌈/-+)⍣⍺⍺(⌽⌊+)⍳⍴1↓⍵}

This takes the string as its right argument, the ratio as its left argument and the direction as its left operand (0 for inward and 1 for outward).

      1 (0 {⍵\⍨0~⍨∊1,⍨1,¨-⌊⍺×(1+⌈/-+)⍣⍺⍺(⌽⌊+)⍳⍴1↓⍵}) 'INTERSTELLAR'
I N  T   E    R     S      T     E    L   L  A R
      0.5 (0 {⍵\⍨0~⍨∊1,⍨1,¨-⌊⍺×(1+⌈/-+)⍣⍺⍺(⌽⌊+)⍳⍴1↓⍵}) 'INTERSTELLAR'
IN T E  R  S   T  E  L L AR
      2 (1 {⍵\⍨0~⍨∊1,⍨1,¨-⌊⍺×(1+⌈/-+)⍣⍺⍺(⌽⌊+)⍳⍴1↓⍵}) 'CODEGOLF'
C        O      D    E  G    O      L        F
      0.4 (1 {⍵\⍨0~⍨∊1,⍨1,¨-⌊⍺×(1+⌈/-+)⍣⍺⍺(⌽⌊+)⍳⍴1↓⍵}) 'CODEGOLF'
C O DEGO L F

Explanation:

  • ⍳⍴1↓⍵: get a list of numbers from 1 to N-1, where N is the length of the string
  • (⌽⌊+): invert the list, and at each position, get the lowest number of both lists (this gives the sizes of the gaps if increasing inwards)
  • (1+⌈/-+)⍣⍺⍺: subtract each number in the list from the highest number in the list, and add 1. Do this ⍺⍺ times. (If ⍺⍺=0, nothing will happen, and if ⍺⍺=1, this will give the sizes of the gaps if increasing outwards.)
  • -⌊⍺×: multiply each gap by , round it downwards, and negate it.
  • ∊1,⍨1,¨: add a 1 in front of each gap, and a 1 at the very end of the list.
  • 0~⍨: remove any zeroes.
  • ⍵\⍨: use the resulting list to expand . Expand (\) works in the following manner: for each positive number, the current character is replicated that many times, and for each negative number, that many spaces are inserted, with the caveat that 0 and ¯1 do the same thing, which is why all the zeroes had to be removed earlier.
\$\endgroup\$
1
\$\begingroup\$

MATL, 31 bytes

nq:tPvX<i?tX>Qw-]*kQ1whYs''1Gb(

Inputs are: string; 0 or 1 for inward or outward increasing; multiplier.

Try it online!

Explanation

Consider inputs 'INTERSTELLAR', 1, 0.5 as an example.

nq:    % Input string implicitly. Push [1 2 ... N-1] where N is the string length
       %   STACK: [1 2 3 4 5 6 7 8 9 10 11]
tP     % Duplicate, reverse
       %   STACK: [1 2 3 4 5 6 7 8 9 10 11], [11 10 9 8 7 6 5 4 3 2 1]
vX<    % Vertically concatenate. Minimum of each column
       %   STACK: [1 2 3 4 5 6 5 4 3 2 1]
i      % Input direction flag
       %   STACK: [1 2 3 4 5 6 5 4 3 2 1], 1
?      % If input flag was 1 (meaning outward increasing)
  tX>  %   Duplicate. Maximum
       %     STACK: [1 2 3 4 5 6 5 4 3 2 1], 6
  Q    %   Add 1
       %     STACK: [1 2 3 4 5 6 5 4 3 2 1], 7
  w-   %   Swap. Subtract
       %     STACK: [6 5 4 3 2 1 2 3 4 5 6]
]      % End
*k     % Input multiplier implicitly. Multiply. Round down
       %   STACK: [3 2 2 1 1 0 1 1 2 2 3]
Q      % Add 1
       %   STACK: [4 3 3 2 2 1 2 2 3 3 4]
1wh    % Prepend a 1
       %   STACK: [1 4 3 3 2 2 1 2 2 3 3 4]
Ys     % Cumulative sum
       %   STACK: [1  5  8 11 13 15 16 18 20 23 26 30]
''     % Push empty string
       %   STACK: [1  5  8 11 13 15 16 18 20 23 26 30], ''
1G     % Push input string again
       %   STACK: [1  5  8 11 13 15 16 18 20 23 26 30], '', 'INTERSTELLAR'
b      % Bubble up
       %   STACK: '', 'INTERSTELLAR', [1  5  8 11 13 15 16 18 20 23 26 30]
(      % Assign the characters from the top string into the empty string at the 
       % given positions. Intermediate positions are filled with character 0, 
       % which is displayed as a space
       %   STACK: 'I   N  T  E R ST E L  L  A   R'
       % Dispaly implicitly
\$\endgroup\$
1
\$\begingroup\$

Racket 348 bytes

(define(f s)(let*((c #\space)(sp(λ(l)(define ol'())(for((i(length l)))(for((j i))
(set! ol(cons c ol)))(set! ol(cons(list-ref l i)ol)))(for((n(floor(/(length l)2))))
(set! ol(cons c ol)))ol))(m(floor(/(string-length s)2)))(s1(sp(string->list(substring s 0 m)
)))(s2(sp(reverse(string->list(substring s m))))))(list->string(append(reverse s1)s2))))

Ungolfed:

(define(f s)
  (let* ((c #\space)
         (sp (λ (l)           ; subfn to add increasing spaces to list of characters
               (define ol '())
               (for ((i (length l)))
                 (for ((j i))
                   (set! ol (cons c ol)))
                 (set! ol (cons (list-ref l i)ol)))
               (for ((n (floor(/ (length l)2)))) 
                 (set! ol (cons c ol)))
               ol))
         (m (floor (/ (string-length s) 2)))                 ; find midpoint
         (s1 (sp (string->list (substring s 0 m))))          ; add spaces to first part
         (s2 (sp (reverse (string->list (substring s m)))))) ; add spaces to second part
    (list->string (append (reverse s1) s2))                  ; re-combine 2 parts
    ))

Testing:

(f "INTERSTELLAR")

Output:

"I N  T   E    R     S      T     E    L   L  A R"
\$\endgroup\$
1
\$\begingroup\$

PHP, 129 Bytes

12 Bytes saved by @Titus Thank You

string = $argv[1],ratio = $argv[2], direction = $argv[3] inward = 0 ,Outward =1

for($i=0;$i+1<2*$l=strlen($t=($x=$argv)[1]);)echo$i%2?str_pad("",$x[2]*abs($x[3]*(0^$l/2+1)-($i++>=$l?$l-$i/2:$i/2))):$t[$i++/2];
\$\endgroup\$
  • \$\begingroup\$ str_pad should save 4 bytes. Try ++$i>$l?$l-$i/2:$i/2 and $t[$i++]/2 instead of increment in loop post-condition; that should save 9. Why 0^? \$\endgroup\$ – Titus Oct 10 '16 at 15:09
  • \$\begingroup\$ @Titus 0^3.12 result in 3 which is necessary \$\endgroup\$ – Jörg Hülsermann Oct 10 '16 at 17:39
  • \$\begingroup\$ $i=0 is unnecessary. ++$i> still saves one byte over $i++>=. And You can save one more byte by moving that increment to the pre-condition: ++$i<2*$l=... instead of $i+1<2*$l=..., swap true and false branches of the outer ternary, $i instead of ++$i and $t[$i/2-.5] instead of $t[$i++/2]. \$\endgroup\$ – Titus Oct 11 '16 at 17:07
  • \$\begingroup\$ Defining inward as 1 and outward as 2, should enable you to save another 3 bytes : ($l>>1) instead of (0^$l/2+1); but I haven´t tested any of these. \$\endgroup\$ – Titus Oct 11 '16 at 17:43
  • \$\begingroup\$ @Titus this will result in greater spaces \$\endgroup\$ – Jörg Hülsermann Oct 11 '16 at 23:05

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.