68
\$\begingroup\$

Oreoorererereoo

Given an input string that is similar to the word "oreo", give an ASCII representation of the cookie that is as wide as the input string (to ensure cookie stability).

Rules

  • The input is lowercase, a non-empty string with no whitespace containing any combination of the strings "o" and "re", and containing only those strings.
  • The string "o" represents the solid cookie, while the string "re" represents the filling.
  • The output must be a stacked cookie that is as wide as the input string.
  • The output may not be an array of strings
  • The cookie must overlap the filling by one character on each side
  • The characters used for the output don't have to match the output below (█ and ░), they just have to be different non-whitespace characters for the two parts of the cookie
  • The whitespace padding on the left side of the filling is required, and any trailing whitespace is optional

Examples

Input: oreo
Output:
████
 ░░ 
████

Input: o
Output:
█

Input: re
Output: (two spaces)


Input: rere
Output:
 ░░ 
 ░░ 

Input: oreoorererereoo
Output:
███████████████
 ░░░░░░░░░░░░░ 
███████████████
███████████████
 ░░░░░░░░░░░░░ 
 ░░░░░░░░░░░░░ 
 ░░░░░░░░░░░░░ 
 ░░░░░░░░░░░░░ 
███████████████
███████████████

Since this is code golf the shortest answer wins, good luck :)

\$\endgroup\$
6
  • 4
    \$\begingroup\$ "The whitespace padding on each side of the filling is required". Does this actually mean that there must be a space character at the end of each line of filling? If so why? As long as it works visually then what does this requirement add to the challenge? \$\endgroup\$
    – ElPedro
    Jan 6, 2019 at 0:23
  • \$\begingroup\$ @ ElPedro Good point, I modified the rules and @Dennis I edited the rules so the comments should be okay to clean up \$\endgroup\$
    – GammaGames
    Jan 7, 2019 at 3:22
  • \$\begingroup\$ @JonathanAllan Since it's printing "ascii-art" I removed that rule, it looks like I forgot to update the question. Should be updated now. \$\endgroup\$
    – GammaGames
    Jan 7, 2019 at 16:05
  • \$\begingroup\$ Awesome, thanks! \$\endgroup\$ Jan 7, 2019 at 16:18
  • \$\begingroup\$ @GammaGames, if whitespace on the right is not required anymore, I assume the output for test case re should be now acceptable as 1 or 2 spaces, not necessarily 2? \$\endgroup\$
    – Kirill L.
    Jan 10, 2019 at 8:24

51 Answers 51

1
2
2
\$\begingroup\$

Python 2, 77 76 72 bytes

lambda i:'\n'.join((x*len(i),' '+x*(len(i)-2))[x>'o']for x in i if'e'<x)

Try it online!

The outer part of the cookie is 'o' and the filling is 'r'.

\$\endgroup\$
8
  • \$\begingroup\$ 68 bytes. Although I doubt if you can really omit the trailing spaces, the spec does say "The whitespace padding on each side of the filling is required"... \$\endgroup\$ Jan 5, 2019 at 22:35
  • \$\begingroup\$ Thanks @EriktheOutgolfer. Thought a lambda would be shorter! Guess in this case not. Had missed the requirement about the mandatory trailing space on the filling. Really can't see the point with an ascii art challenge but if that's what OP requires then I guess my answer is invalid anyway. \$\endgroup\$
    – ElPedro
    Jan 6, 2019 at 0:13
  • \$\begingroup\$ Now corrected... \$\endgroup\$
    – ElPedro
    Jan 6, 2019 at 0:18
  • \$\begingroup\$ Why bring it back to 76? Just put +' ' after (l-2). Also, you have a typo, *' ' must be +' '. \$\endgroup\$ Jan 6, 2019 at 0:23
  • \$\begingroup\$ That's what I did with my current solution. Will take a closer look at your hints tomorrow (later today). It's late here and I have been shoveling snow all day so too tired for golf. Thanks for the tips though :) \$\endgroup\$
    – ElPedro
    Jan 6, 2019 at 0:27
2
\$\begingroup\$

x86-64 machine code (Linux), 97 bytes

0000000000000000 <oreo_asm>:
   0:   56                      push   %rsi
   1:   57                      push   %rdi

0000000000000002 <len>:
   2:   48 ff c7                inc    %rdi
   5:   80 3f 00                cmpb   $0x0,(%rdi)
   8:   75 f8                   jne    2 <len>
   a:   49 89 fc                mov    %rdi,%r12
   d:   5f                      pop    %rdi
   e:   49 29 fc                sub    %rdi,%r12
  11:   4d 31 f6                xor    %r14,%r14
  14:   eb 18                   jmp    2e <outer_loop.skip>

0000000000000016 <extra>:
  16:   41 c6 01 20             movb   $0x20,(%r9)
  1a:   c6 03 20                movb   $0x20,(%rbx)
  1d:   49 ff ce                dec    %r14
  20:   eb 06                   jmp    28 <outer_loop>

0000000000000022 <newline>:
  22:   c6 06 0a                movb   $0xa,(%rsi)
  25:   48 ff c6                inc    %rsi

0000000000000028 <outer_loop>:
  28:   49 ff c6                inc    %r14
  2b:   48 ff c7                inc    %rdi

000000000000002e <outer_loop.skip>:
  2e:   44 8a 07                mov    (%rdi),%r8b
  31:   41 80 f8 65             cmp    $0x65,%r8b
  35:   74 df                   je     16 <extra>
  37:   45 84 c0                test   %r8b,%r8b
  3a:   74 23                   je     5f <done>
  3c:   48 89 f3                mov    %rsi,%rbx

000000000000003f <inner_loop>:
  3f:   44 88 06                mov    %r8b,(%rsi)
  42:   49 89 f1                mov    %rsi,%r9
  45:   48 ff c6                inc    %rsi
  48:   48 31 d2                xor    %rdx,%rdx
  4b:   48 89 f0                mov    %rsi,%rax
  4e:   48 2b 04 24             sub    (%rsp),%rax
  52:   4c 29 f0                sub    %r14,%rax
  55:   49 f7 f4                div    %r12
  58:   48 85 d2                test   %rdx,%rdx
  5b:   74 c5                   je     22 <newline>
  5d:   eb e0                   jmp    3f <inner_loop>

000000000000005f <done>:
  5f:   5e                      pop    %rsi
  60:   c3                      retq

This x86-64 function takes in the pointer to the input string in rsi and builds the output starting at the pointer in rdi (these are the registers used to pass the first two arguments from a C function on Linux). For convenience, I've written a C++ wrapper for this which also does nice input sanitization and prints the output. That code can be located here. This also shows the original nasm syntax assembly I wrote for this function (as well as the non-golfed version I got working first).

A few things to note is that this code doesn't respect any callee saved registers, which means that the C++ code likely will crash if run for a while after calling this function. On my machine it doesn't, but that's rather surprising. I also don't add a null byte to delimit the output string, and instead the space allocated for the output string is pre-filled with bytes. (If this isn't allowed I can add the null terminator at a cost of 3 bytes).

The logic for this code is essentially counting the length of the string, then building a line of this length for each 'o' and 'r' characters seen in the input string, and then for any 'e' character seen, replacing the first and last characters on the previous line with space characters.

I can't find anywhere online to compile and run a mix of C++ and nasm source code, so I might write some small wrapper code for this to prove it works. Otherwise you should be able to compile and run this with the makefile in the link I gave with the command:

$ make oreo ASM_FILE=oreo_golf.nasm
$ ./oreo oreoorererereoo --use_asm

I was able to format the assembly to something acceptable by gcc, so try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Oh my, now this is an entry! \$\endgroup\$
    – GammaGames
    Jan 8, 2019 at 15:09
2
\$\begingroup\$

C (gcc), -D$=putchar(33 + 88 = 102 bytes

O(char*r){for(char*e,*o=r,x;*r;$-x),$-23))for(x=*r++>111,e=x?$-1),r++,o+1:o;*++e;$+x));}

Try it online!

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

Sed, 89 characters

(86 characters code + 3 characters command line option)

h;s/./E/g;H;g;s/\n//;:b;s/(o|re)([ore]+)(E*)/\1\3\n\2\3/;tb;s/o//g;s/reE(E*)E/ \L\1 /g

Commented with example for input “oreo”:

h        # copy to hold space
s/./E/g  # change into cookie: EEEE
H        # append to hold space
g        # copy back to pattern space: oreo␤EEEE
s/\n//   # remove the newline: oreoEEEE

:b                                 # split the os and res in separate lines
  s/(o|re)([ore]+)(E*)/\1\3\n\2\3/ # repeating the EEEE for each:
tb                                 # oEEEE␤reEEEE␤oEEEE

s/o//g                # remove the os: EEEE␤reEEEE␤EEEE
s/reE(E*)E/ \L\1 /g   # remove the res, cut edge, change fill: EEEE␤ ee ␤EEEE

Sample run:

bash-4.4$ sed -r 'h;s/./E/g;H;g;s/\n//;:b;s/(o|re)([ore]+)(E*)/\1\3\n\2\3/;tb;s/o//g;s/reE(E*)E/ \L\1 /g' <<< oreoorererereoo
EEEEEEEEEEEEEEE
 eeeeeeeeeeeee 
EEEEEEEEEEEEEEE
EEEEEEEEEEEEEEE
 eeeeeeeeeeeee 
 eeeeeeeeeeeee 
 eeeeeeeeeeeee 
 eeeeeeeeeeeee 
EEEEEEEEEEEEEEE
EEEEEEEEEEEEEEE

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ I didn't expect an entry like that, creative! \$\endgroup\$
    – GammaGames
    Jan 11, 2019 at 15:04
  • \$\begingroup\$ Same byte count but with newlines - Try it online! \$\endgroup\$
    – Logern
    Jan 11, 2019 at 18:52
  • \$\begingroup\$ @Logern, thanks for playing with it. This brought to my attention that the TIO code was still the first version, which didn't handled input “re” correctly. \$\endgroup\$
    – manatwork
    Jan 11, 2019 at 19:02
2
\$\begingroup\$

APL (Dyalog Extended), 22 bytesSBCS

Anonymous tacit prefix function. Cookies are o, cream is r.

'^rr'⎕R' '⍤1≢⊢⍤/⍪~'e'⍨

Try it online!

 swap the input for:

'e' this letter

~ remove all the "e"s from:

 the columnised argument

⊢⍤/ replicate that single column to be as many columns as:

 the tally of characters in the input

⍤1 on each row (lit. on each 1D sub-array):

'^rr'⎕R' ' PCRE Replace leading "rr" with a single space

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

Stax, 13 bytes

äNëY┬2-]‼Cv6╤

Run and debug it

Uses "o" and "r" characters for the layers.

\$\endgroup\$
1
  • \$\begingroup\$ Oh man, you tied the current lowest! Really cool language too, I appreciate stack-based languages. \$\endgroup\$
    – GammaGames
    Jul 24, 2019 at 14:14
2
\$\begingroup\$

Excel, 93 bytes

=SUBSTITUTE(SUBSTITUTE(A4,"o",REPT("O",LEN(A4))&"
"),"re"," "&REPT("r",MAX(0,LEN(A4)-2))&"
")

MAX(0, is needed to handle o. Uses O and r.

\$\endgroup\$
3
  • \$\begingroup\$ Very cool, though since it is an ascii challenge you should output the text in a stack (probably with CHAR(10) in excel), and you can replace the block characters with letters to cut down a few bytes :) \$\endgroup\$
    – GammaGames
    Nov 18, 2019 at 16:35
  • 1
    \$\begingroup\$ @GammaGames, \n is included in code and bytecount. You need to switch on "Wrap text" to see them though. \$\endgroup\$
    – Wernisch
    Nov 19, 2019 at 11:41
  • \$\begingroup\$ Ah, gotcha. Thank you for your answer! \$\endgroup\$
    – GammaGames
    Nov 19, 2019 at 15:02
2
\$\begingroup\$

Nibbles 10 bytes

&" ",@~.|@%$~
^-,_%$3 # $ 

explanation

&           # Justify
  " "       # (value to pad in justify)
  ,         # length (size to justify to)
    @       # first input string
  ~         # centered
  .         # map
    |       # filter  
      @     # first input string
      %$~   # mod char element 2
    ^       # replicate (begin map body)
     -      # minus
      ,_    # length of first input string
        %$3 # mod char element 3
            # implicit $ (the char element to be replicated)
\$\endgroup\$
2
  • \$\begingroup\$ Coming in lower than jelly! How do I run this? \$\endgroup\$
    – GammaGames
    Dec 22, 2021 at 23:47
  • \$\begingroup\$ echo oreoorererereoo | nibbles filename. It isn't on TIO.run yet, but I've contacted them. \$\endgroup\$ Dec 23, 2021 at 20:35
1
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 136 bytes

	S =INPUT
	N =SIZE(S)
S	S ('o' | 're') . X REM . S	:F(END)
	OUTPUT =IDENT('o',X) DUPL(X,N)	:S(S)
	OUTPUT =' ' DUPL(0,N - 2) ' '	:(S)
END

Try it online!

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

CJam, 27 bytes

q:T'e-{i2%T,'9*_:)2>S\+?N}/

Try it online!

Explanation:

q                            read input:                    | "oreoo"
 :T                          store in variable T            | "oreoo", T="oreoo"
   'e-                       remove all 'e' characters:     | "oroo"
      {                  }/  for each character:            | 'o
       i                       get Unicode value:           | 79
        2%                     modulo 2:                    | 1
          T                    push original input:         | 1 "oreoo"
           ,                   get length:                  | 1 5
            '9*                repeat '9' that many times:  | 1 "99999"
               _               duplicate:                   | 1 "99999" "99999"
                :)             increment every character:   | 1 "99999" ":::::"
                  2>           remove first two characters: | 1 "99999" ":::"
                    S\+        prepend a space:             | 1 "99999" " :::"
                       ?       conditional:                 | "99999"
                        N      add a newline:               | "99999" N
                             (implicit output)              | "99999" N " :::" N "99999" N "99999" N
\$\endgroup\$
2
  • \$\begingroup\$ This breaks the rules: "The whitespace padding on each side of the filling is required" \$\endgroup\$
    – NieDzejkob
    Jan 6, 2019 at 15:19
  • \$\begingroup\$ Sorry, I allowed the optional trailing whitespaces. Nice entry! \$\endgroup\$
    – GammaGames
    Jan 7, 2019 at 3:27
1
\$\begingroup\$

Lua, 112 bytes

s=io.read()for t in s:gmatch"."do io.write(t=="o"and t:rep(#s).."\n"or(t=="r"and" "..t:rep(#s-2).." \n"or""))end

Explanation

s = io.read() -- Reads the input
for t in s:gmatch(".") do -- For each character in the input, call it 't' and enter the loop
 io.write(t=="o" and t:rep(#s).."\n" or (t=="r" and " "..t:rep(#s-2).." \n" or ""))

          t=="o" and  -- if 't' is equal to "o" then
                     t:rep(#s).."\n"  -- you have to write 't' repeated N times, where N is
                                      -- is the size of the input s, appended by a new line
                                     or (t=="r" and  -- else, if 't' is equal to "r" then
                                                    " "..t:rep(#s-2).." \n"  -- write a space, followed by 't' repeated N-2 times,
                                                                             -- where N is the size of the input.
                                                                             -- followed by a space and a new line.
                                                                            or "" -- else, just don't write anything.

end

Try it online!

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

JavaScript, 70 bytes

x=>x.replace(/()()o|re/g,(_,o=1,s=' ')=>s.padEnd(x.length-o,+o)+s+`
`)

Try it online!

Or... If we're allowed to use other characters for whitespace, we can get it down to 65 bytes:

x=>x.replace(/()()o|re/g,(_,o=1,s=' ')=>s.padEnd(x.length-o,+o)+s+`
`)

Try it online!

...but I don't think that counts.

\$\endgroup\$
1
  • \$\begingroup\$ You're right, the padding has to be whitespace. Nice entry! \$\endgroup\$
    – GammaGames
    Jan 7, 2019 at 3:24
1
\$\begingroup\$

JavaScript (Node.js), 65 bytes

s=>s[R='replace'](/.e?/g,x=>s[R](/./g,x[0])[R](/^r|r$/g,' ')+`
`)

Try it online!

Thanks to Yair Rand, saves 2 bytes.

\$\endgroup\$
3
  • \$\begingroup\$ You can save a byte by moving the last replace a bit earlier and removing the m flag: s=>s[R='replace'](/re|o/g,x=>s[R](/./g,x[0])[R](/^r|r$/g,' ')+ ) \$\endgroup\$
    – Yair Rand
    Jan 7, 2019 at 4:09
  • \$\begingroup\$ And another byte by using /.e?/g instead of /re|o/g . \$\endgroup\$
    – Yair Rand
    Jan 7, 2019 at 4:50
  • \$\begingroup\$ @YairRand Thanks. \$\endgroup\$
    – tsh
    Jan 7, 2019 at 5:40
1
\$\begingroup\$

Python 2, 64 bytes

s=input()
for c in s:
	if'n'<c:j='o'<c;print' '*j+c*(len(s)-2*j)

A full program which prints the result.

Try it online! Or see the test-suite.

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

Batch, 133 bytes

@set/ps=
@set o=%s:r=o%
@set o=%o:e=o%
@set r=%o:o=-%
@set r= %r:~2%
@set s=%s:e= %
@for %%c in (%s:o=o %)do @call echo %%%%c%%

Takes input on STDIN. Explanation:

@set/ps=

Input the string.

@set o=%s:r=o%
@set o=%o:e=o%

Make a copy of the string with all of the rs and es replaced with os.

@set r=%o:o=-%
@set r= %r:~2%

Make a copy of the string of os, change them to -s and replace the first two with a space.

@set s=%s:e= %
@for %%c in (%s:o=o %)do @call echo %%%%c%%

Change the es into spaces and also add a space after each o, allowing the os and rs to be iterated over, printing the appropriate string each time.

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

Python 2, 70 75 bytes

lambda s:"\n".join((c*(len(s)-2*(c<'f'))).center(len(s))for c in s if'r'>c)

Try it online!

Uses 'o' for cookie, 'e' for filling. Returns a string.

EDIT: Saved 4 bytes thanks to Jo King.

Explanation:

# anonymous function, returns a string seperated by line breaks
lambda s:"\n".join(.......................................................)
                                                        # iterate through string, return each non-'r' character
                                                        for c in s if'r'>c
                    # duplicate the character until it is the length of the original string,
                    # minus two characters if the current letter is 'e'
                    c*(len(s)-2*(c<'f'))
                   # pad the string with spaces out to the length of the original string
                   (....................).center(len(s))
\$\endgroup\$
3
  • \$\begingroup\$ Sorry, the output should be a single string with line-breaks that can be printed or the program should print the output as it is processed. Arrays of strings aren't allowed, because of the "ascii" part. \$\endgroup\$
    – GammaGames
    Jan 7, 2019 at 19:13
  • \$\begingroup\$ @GammaGames Bluh, I should really read the rules more closely. Thank you! \$\endgroup\$ Jan 7, 2019 at 20:22
  • \$\begingroup\$ 66 bytes \$\endgroup\$
    – Jo King
    Jan 8, 2019 at 3:32
1
\$\begingroup\$

Tcl, 216 bytes

set s [gets stdin]
set l [string map {o { o } re { re }} $s]
set n [string length $s]
foreach i $l {
if {$i eq "o"} {
puts [string repeat █ $n]
} elseif {$i eq "re"} {
puts " [string repeat ░ [expr {$n-2}]] "
}
}

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Assume valid input and handle “o” and “r” and ignore “e”. For this split $s "" is shorter than string map. You only need $l once, so better skip the assignment to variable and use the expression directly in foreach. If you reverse the conditions, you can remove the spaces: $i eq "o""o"eq$i. Use if instead of elseif. no need the braces around expr's argument. Try it online! \$\endgroup\$
    – manatwork
    Jan 9, 2019 at 19:26
1
\$\begingroup\$

Vyxal j, 23 bytes

L£\eoƛ\o=[×¥*|ð¥⇩\!*ð++

Try it Online!

L£                      # Store length to register
  \eo                   # Remove es
     ƛ                  # Map...
      \o=[              # If o then
          ×¥*           # (Register) asterisks
             |          # Else...
               ¥⇩\!*    # (Register-2 !s)
              ð     ð++ # Padded with spaces
\$\endgroup\$
1
\$\begingroup\$

Perl 5 + -F -M5.10.0, 35 bytes

say/o/?E x@F:$".n x(@F-2)for/o|re/g

Try it online!

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

Vyxal j, 14 bytes

\eoƛAd⇩?L+*?L⋏

Try it Online!

\$\endgroup\$
1
  • \$\begingroup\$ Coming in lower than the other Vyxal answer, nice work! \$\endgroup\$
    – GammaGames
    Jan 6 at 15:40
1
\$\begingroup\$

APOL, 79 bytes

This could almost certaintly be made shorter.

v(0 i);j(ƒ(R(⁰ "re" "*") ¿(=(∋ "*") +(" " *("r" -(l(⁰) 2))) *("o" l(⁰)))) "\n")

Explanation

v(0 i);  Put user's input at memory index 0
j(  List join
  ƒ(  Listbuilder for
    R(  String replace (being iterated through)
      ⁰  Value at index 0
      "re"  Replace "re"
      "*"  with "*"
    )
    ¿(  Returning if (called for each character in replaced string)
      =(  Equals (condition)
        ∋  Current character
        "*"  The string "*"
      )
      +(  Add (true instruction, used here to join strings)
        " "  The string " " (the padding for the filling)
        *(  Multiply (used here to repeat a string)
          "r"  The string "r" (our filling) by
          -(  Subtract
            l(⁰)  The length of the input
            2  from two (one for each character of padding)
          )
        )
      )
      *(  Multiply (the false condition)
        "o"  The string "o"  (our cookie)
        l(⁰)  by the length of the input
      )
    )
  )
  "\n"  Join each string with a newline
)
\$\endgroup\$
1
2

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.