13
\$\begingroup\$

Write a program in any language that reads input from stdin and outputs a slightly modified output to stdout. The program should borrow some characters from the input and output as large of a prefix as possible of *language-name* is awesome! followed by a newline and then what's left of the input.

  • The input does not contain any uppercase characters.
  • If the first character of the language name is not present in the string, only the newline character should be borrowed.
  • If there's no newline character in the input, output the input unmodified.
  • It does not matter which of the available characters you borrow.

I'm using \nas the newline character (0x0a) to save space when writing. The real program should only care about the real newline character, not the \n string.

Example: python.
input: abcdefghijklmnopqrstuvwxyz\n0123456789
output: python\nabcdefgijklmqrsuvwxz0123456789
Since the input does not have any spaces, we cannot continue even though we have enough characters for the next word: is.

Example: C.
input: i don't see anything!
output: i don't see anything!
C was not found in the string, so no modification was possible. Also, no newline character is present.

Example: C++.
input: i don't\nsee anything!
output: \ni don'tsee anything!
C was not found in the string, so no modification was possible.

Example: Obj-C.
input: objectively, clojure is amazing.\nq.e.d.
output: obj\nectively, clojure is amazing.q.e.d.
The input contains enough characters to write obj but the - is missing.

Byte count of your source code minus the byte count of your languages' name, utf-8 encoded (if possible), is your score; lowest wins!

\$\endgroup\$
9
  • 4
    \$\begingroup\$ Let's hope someone finds a language with a lot of repetition in the name for a negative score :) \$\endgroup\$
    – Drathier
    Commented Oct 24, 2015 at 17:06
  • \$\begingroup\$ Could you include i don't\nsee anything! as a test case? \$\endgroup\$
    – Dennis
    Commented Oct 24, 2015 at 19:51
  • \$\begingroup\$ Good test case! Added. \$\endgroup\$
    – Drathier
    Commented Oct 24, 2015 at 19:54
  • \$\begingroup\$ How should cases with repeated characters (either in the name or in the input) be handled? Does the order of the left-over characters in the output matter? \$\endgroup\$ Commented Oct 24, 2015 at 20:32
  • 2
    \$\begingroup\$ Could you please add a test-case that uses is awesome, and one that contains the necessary letters but not a newline? \$\endgroup\$ Commented Oct 26, 2015 at 1:23

8 Answers 8

4
\$\begingroup\$

Pyth, 37 bytes

.-Jjb.zpef!.-TJ+,kb+Rb._"pyth is awesome!

The source code is 41 bytes long. Try it online.

How it works

  Jjb.z                                      Save all user input in J.
                      ._"pyth is awesome!    Compute all prefixes that string:
                                               ["p", "py", ... ]
                   +Rb                       Append a linefeed to each prefix.
               +,kb                          Concatenate ["", "\n"] with the result.
         f                                   Filter the resulting array; for each T:
           .-TJ                                Perform bagwise difference between T
                                               and J (respects multiplicities).
         !                                     Take the logical NOT.
                                             Keep T if ! returned True, i.e., if J
                                             contains all of T's characters.
        e                                    Retrieve the last, longest match.
       p                                     Print it.
.-J                                          Remove its characters from J.
                                             (implicit) Print the result.
\$\endgroup\$
2
\$\begingroup\$

Python, 186 - 6 = 180

import sys
a=sys.stdin.read()
s="python is awesome!"
r=''
if'\n'not in a:print a;exit()
a=a.replace('\n','',1)
for c in s:
 if c in a:a,r=a.replace(c,'',1),r+c
 else:break
print r+'\n'+a

Try it online

\$\endgroup\$
1
  • \$\begingroup\$ It should only borrow characters, so if multiple newlines are present in the input, you only borrow one of them. All the characters should still be there in the output, but not necessarily in the same order. \$\endgroup\$
    – Drathier
    Commented Oct 24, 2015 at 17:13
1
\$\begingroup\$

Python, 146 bytes

import sys
r=sys.stdin.read();y='\npython is awesome!';a=''
for i in y:
    if i in r:a+=i
    else:break
print a[1:]+'\n'+''.join(b for b in r if not b in a)
\$\endgroup\$
2
  • \$\begingroup\$ @Dennis fixed it -_- \$\endgroup\$
    – TheDoctor
    Commented Oct 24, 2015 at 19:38
  • \$\begingroup\$ Still one newline too many if the input doesn't contain newlines (second example). \$\endgroup\$
    – Dennis
    Commented Oct 24, 2015 at 19:50
1
\$\begingroup\$

Ceylon, 235 - 6 = 229

void a(){variable value i="";variable value r="\nceylon is awesome!";while(exists l=process.readLine()){i=i+"\n"+l;}i=i.rest;for(j->c in r.indexed){if(c in i){i=i.replaceLast(c.string,"");}else{r=r[0:j];break;}}print(r.rest+r[0:1]+i);}

Here is a formatted and commented version:

void a() {
    // our target string, with the \n shuffled to the start.
    variable value r = "\nceylon is awesome!";

    // read the whole input line by line
    // (there doesn't seem a way to do this shorter :-/)
    variable value i = "";
    while (exists l = process.readLine()) {
        i = i + "\n" + l;
    }
    // remove first \n:
    i = i.rest;
    for (j->c in r.indexed) {
        if (c in i) {
            // remove some occurence of c
            i = i.replaceLast(c.string, "");
        } else {
            // stop the loop, and take the part of `r` processed so far.
            r = r[0:j];
            break;
        }
    }
    // reshuffle first \n in r to its end.
    // This will result in the empty string if r is empty, i.e. no \n was found.
    print(r.rest + r[0:1] + i);
}

It uses replaceLast instead of replaceFirst because it is shorter.

Some example inputs and outputs in the same format as in the question:

  • abcdefghijklmnopqrstuvwxyz\n0123456789ceylon\nabdfghijkmpqrstuvwxz0123456789
  • i don't see anything!i don't see anything!
  • i don't\nsee anything!\ni don't see anything!
  • objectively, closure is amazing.\nq.e.d.ceylon is a\nobjectivel, sureiamzng.\q..d.
\$\endgroup\$
0
1
\$\begingroup\$

Jelly, 23 - 5 = 18 bytes

“£İþ¬Ɠ¥ỊḊ»
¢œ-ƤṆ€×¢Ṅœ-@

Try it online!

This uses the Jelly encoding. Insisting on UTf-8 encoding has the same byte count, it just means I need to make a hexdump of the bytes.

How it works

“£İþ¬Ɠ¥ỊḊ» - Helper link. Compressed string "jelly is awesome"

¢œ-ƤṆ€×¢Ṅœ-@ - Main link. Takes S on the left
¢            - Yield "jelly is awesome"
   Ƥ         - Over each prefix of "jelly is awesome":
 œ-          -   For each character in the prefix, remove it exactly once
                  if it is in the input
                  This results in an empty list if the entire prefix is in
                  the input else a non-empty list
     €       - Over each:
    Ṇ        -   Logical NOT. This yields 1 for an empty list, else 0
       ¢     - Yield "jelly is awesome"
      ×      - For each character, keep it if the left argument is 1
        Ṅ    - Print the kept characters with a trailing newline
         œ-@ - Remove exactly one occurrence of each of the kept characters
               from the input and output that
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6) 90 (100-10)

As a function returning the requested ouput. It's difficult to implement with I/O, as the usual substitute for STDIN is prompt(), that does not accept a newline inside the input string.

As a function with real output (using alert) the byte count is 107

f=s=>alert(([...`
javascript is awesome`].every(c=>(z=s.replace(c,''))!=s&&(s=z,q?o+=c:q=c),q=o=''),o+q+z))

Test running the snippet below in an EcmaScript 6 compliant browser (implementing spread operator and arrow function - I use FireFox)

f=s=>([...`
javascript is awesome`].every(c=>(z=s.replace(c,''))!=s&&(s=z,q?o+=c:q=c),q=o=''),o+q+z)

function test()
{
  O.innerHTML=f(I.value)
}

test()
#I {width: 80%}
<textarea id=I>
objectively, clojure is amazing.
q.e.d.</textarea><button onclick="test()">-></button>
<pre id=O></pre>

\$\endgroup\$
0
0
\$\begingroup\$

Perl, 72 - 4 = 68 bytes

Includes 2 switches.

perl -0pe 'for$c("\nperl is awesome!"=~/./gs){s/$c//?$p.=$c:last}s/^/$p\n/;s/\n//'

Explanation: For every character in the string "\nperl is awesome", remove the corresponding character from the input string ($_) till we find a character not present in $_. The matching characters are stored in $p which is prefixed to $_ which is then printed.

The -0 switch reads in the complete input rather than line-by-line and the -p switch makes reading input and print the output implicit.

\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES7), 101 107 - 10 = 97

It was shorter before, and even worked on all four test cases, but apparently I missed a rule, so....

x=>(i=r=q='',[for(c of`
javascript is awesome`)(y=x.replace(c,''),i||y==x?i=1:(c<' '?q=c:r+=c,x=y))],r+q+x)

Works properly in Firefox 42. This originally started out at 119 bytes, but a trick from @edc65's answer helped to shorten it a great deal. I think there's still some room for improvement. As always, suggestions welcome!

\$\endgroup\$
2
  • \$\begingroup\$ Fails when missing newline in input. Test obj -> job, should be not modified (rule 3) \$\endgroup\$
    – edc65
    Commented Oct 25, 2015 at 21:52
  • \$\begingroup\$ @edc65 Ah, yes, the test cases only cover 75% of the edge cases. I could even remove is awesome and it would still work properly on all four of them. I'll fix this ASAP. \$\endgroup\$ Commented Oct 26, 2015 at 1:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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