22
\$\begingroup\$

A Quat is a combination of a and the popular esolang cat program.

Challenge

The challenge is to write a standard cat program. Whatever the user inputs, the program will echo the input to stdout.
However, when the length of the input is greater than 0 and a multiple of 4, the program should output its own source code. Quat comes from the Portuguese quatro, which translates to 'four'.

Rules

  • Standard loopholes apply
  • You may not read the source code from a file
  • An empty input should produce an empty output

Bonus

If your input length is a multiple of 4 you can earn a 25% bonus by printing the quine length/4 times. Another 5% bonus if you seperate the output by spaces (no trailing space allowed).

Test cases

The following test cases apply for the program in%4=0?cat:self (not a real language).

<empty input> -> <empty output>
input -> input
1234 -> in%4=0?cat:self
12345678 -> in%4=0?cat:self 0% bonus
12345678 -> in%4=0?cat:selfin%4=0?cat:self 25% bonus
12345678 -> in%4=0?cat:self in%4=0?cat:self 30% bonus

Scoring

This is . Shortest code in bytes wins.

\$\endgroup\$
  • \$\begingroup\$ Can the input have multiple lines? \$\endgroup\$ – LegionMammal978 Dec 10 '15 at 23:14
  • \$\begingroup\$ @LegionMammal978 Ofcourse, let \n be the new line character, for 1 byte of input \$\endgroup\$ – Bassdrop Cumberwubwubwub Dec 11 '15 at 8:36
  • \$\begingroup\$ Okay, it just complicates input in my language, which must be read one line at a time. \$\endgroup\$ – LegionMammal978 Dec 11 '15 at 11:20
  • \$\begingroup\$ Are built-ins for quines allowed? (see: Seriously) \$\endgroup\$ – Addison Crump Dec 11 '15 at 11:48
  • \$\begingroup\$ @FlagAsSpam I don't mind, but I think a meta-post is more appropriate here. \$\endgroup\$ – Bassdrop Cumberwubwubwub Dec 11 '15 at 12:16

10 Answers 10

8
\$\begingroup\$

CJam, 23 * 0.75 = 17.25 bytes

Standard generalised quine...

{`"_~"+q:Q,4md@@*Q\?}_~

or

{`"_~"+q_,4md@@]:\*?}_~

Test it here.

Explanation

{`"_~"+  e# Generalised quine framework. Leaves the source code on the stack.
  q:Q    e# Read input and store it in Q.
  ,      e# Get its length.
  4md    e# Divmod 4.
  @      e# Pull up the source code.
  @      e# Pull up the div.
  *      e# Repeat the source code that many times.
  Q\     e# Push the input and swap it below the repeated source.
  ?      e# Pick the right output based on the modulo.
}_~

The other version avoids the use of a variable by using the stack-rotation trick ]:\.

\$\endgroup\$
4
\$\begingroup\$

Seriously, 8 9 bytes

Q,ó;l4@%I

Try it Online

(Hit enter once in the input box to test empty input.)

The first bonus can be done in 12 bytes (16*.75):

Q,ó;l;4@\(*)4@%I

Explanation:

Q                   Push program source to stack
 ,ó                 Push input string, and terminate if it's empty
   ;l               Push length of input
     4@%            Take the length mod 4.
        I           Pick the next stack element (input) if nonzero,
                    else the next next (program source)

Since some people don't like the use of Seriously's quining built-in, I provide this 22 byte version that doesn't use Q for reference:

`è";ƒ"(+,ó;l4@%I`;ƒ

If you are one of those people, consider this the definitive version (for now) and then go start a meta thread about the use of built-ins in quines.

\$\endgroup\$
  • 6
    \$\begingroup\$ In a quine challenge, I believe you cannot read the program source. \$\endgroup\$ – Conor O'Brien Dec 10 '15 at 20:32
  • 3
    \$\begingroup\$ The instructions say you cannot read it from a file. Q is a built-in command that pushes the source to the stack when it is empty. I think this falls under "playing to the language's strengths" \$\endgroup\$ – quintopia Dec 10 '15 at 20:38
  • 4
    \$\begingroup\$ I think a built-in quining function does read the source code. That's like using a built-in for a binomial coefficient challenge, when the challenge says "no built-in factorials". \$\endgroup\$ – Martin Ender Dec 10 '15 at 23:35
  • 4
    \$\begingroup\$ Q does not read the program's source from a file, technically - it's in RAM, stored by the interpreter. Since the rule specifically states "from a file", this should be valid. \$\endgroup\$ – Mego Dec 11 '15 at 2:25
  • 3
    \$\begingroup\$ I don't really understand why this is more popular than any previous languages with built-in quine operators, including HQ9+ and Ismael's MarioGolf. But in any case your program doesn't seem to work correctly for empty input. \$\endgroup\$ – Martin Ender Dec 11 '15 at 8:17
2
\$\begingroup\$

Pyth, 33 * .75 = 24.75

?%lz4z*/lz4jN*2]"?%lz4z*/lz4jN*2]

Test Suite

Standard Pyth quine using join. This is only a true quine on the online interpreter, which doesn't add a final trailing newline.

Getting the final bonus reults in a score of 39 * .7 = 27.3:

?%lz4zjd*/lz4]jN*2]"?%lz4zjd*/lz4]jN*2]
\$\endgroup\$
2
\$\begingroup\$

Vitsy, 18 17 bytes

So close. Yus. I am now winning amongst non-built in quiners! glares at Seriously

zl4M([&'rd3*8\}]Z
z                 Grab ALL THE INPUT! :D
 l4M([         ]  If the input is a multiple of four, do the stuff in brackets.
      &           Generate a new stack and move to it.
       'rd3*      Standard quine.
            8\}   Push the bottom 8 items of the stack to the top.
                Z Output the current stack.

There's no reason for me to go after the bonuses - they'd chuck on a lot more bytes.

Cheating quine version, 12 bytes:

zl4M([&iG`]Z
zl4M([&   ]Z  Same as above.
       i      Push -1.
        G     Get the name of the file with this index of use (-1 is self)
         `    Read the file with the given name and push its contents to the stack.
\$\endgroup\$
  • \$\begingroup\$ G` is cool! It seems more legit than a simple Q command. \$\endgroup\$ – Conor O'Brien Dec 11 '15 at 13:17
  • \$\begingroup\$ Seems less legit to me, seeing as how it requires file I/O. \$\endgroup\$ – quintopia Dec 11 '15 at 13:42
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Quintopia is right - just because I get the file reference doesn't mean it's any better. :P \$\endgroup\$ – Addison Crump Dec 11 '15 at 16:39
2
\$\begingroup\$

Emacs Lisp (323 * 0.75 = 242.25)

((lambda (s) (let* ((a (read-string "")) (l (string-bytes a))) (if (> (% l 4) 0) (message a) (dotimes (v (/ l 4)) (prin1 (list s (list (quote quote) s))))))) (quote (lambda (s) (let* ((a (read-string "")) (l (string-bytes a))) (if (> (% l 4) 0) (message a) (dotimes (v (/ l 4)) (prin1 (list s (list (quote quote) s)))))))))

This uses Lisp's quoting mechanic to give the source code as input to itself.

Old cheating version

:; exec emacs -Q -script $0
(find-file(nth 2 command-line-args))(set'b(buffer-string))(set's(read-string""))(set'l(string-bytes s))(if(>(% l 4)0)(message s)(dotimes(v(/ l 4))(message"%s"b)))

Ungolfed:

:; exec emacs -Q -script $0
(find-file(nth 2 command-line-args)) ; open self
(set'b(buffer-string))               ; read own code to string
(set's(read-string""))               ; read input
(set'l(string-bytes s))              ; length of input
(if(>(% l 4)0)                       ; l % 4 > 0 ?
    (message s)                      ; output input
  (dotimes(v(/ l 4))                 ; (implicit else) repeat l/4 times
    (message"%s"b)))                 ; output own code
\$\endgroup\$
  • 2
    \$\begingroup\$ Doesn't this violate the rule that "You may not read the source code from a file"? \$\endgroup\$ – ThisSuitIsBlackNot Dec 10 '15 at 20:36
  • \$\begingroup\$ @ThisSuitIsBlackNot you're right... guess I'll have to look for a non-cheating Quine in Elisp \$\endgroup\$ – Lord Yuuma Dec 11 '15 at 11:18
1
\$\begingroup\$

JavaScript, 57 56 72 bytes * 0.75 = 54

Thanks to @Neil for a one byte savings!

(f=_=>alert(!(p=prompt())||(l=p.length)%4?p:`(f=${f})()`.repeat(l/4)))()

The shortest solution I could find was pretty straight-forward.

So, here's a couple bonus (more interesting) solutions:

JavaScript, 82 81 bytes * 0.75 = 60.75

f=_=>{try{p=prompt();a=`f=${f};f()`.repeat(p.length/4)}catch(e){a=p}alert(a)};f()

This one abuses repeat's functionality of throwing an exception if passed a non-integer.

JavaScript, 83 bytes * 0.70 = 58.1

(f=_=>alert((a=(p=prompt()).split(/.{4}/)).pop()?p:a.fill(`(f=${f})()`).join` `))()

This last one is definitely my favorite, splitting the input on every four characters using the regex /.{4}/. If there are any characters left at the end of the string when we pop, it isn't divisible by 4, so alert the input. Otherwise, the pop reduced the array's length by one, so at this point the array's length is equal to the input length / 4. In this case, just fill it with the quine and join with spaces.

\$\endgroup\$
  • \$\begingroup\$ I think you can save a byte by inverting the condition; change the && to ||, put a ! before the (p=prompt()), remove the <1 and move the p to be on the inside of the ?:. \$\endgroup\$ – Neil Dec 11 '15 at 0:29
1
\$\begingroup\$

Perl, 68 65 * 0.75 = 48.75 bytes

perl -e'$_=q{print+($l=($~=<>)=~y///c)%4?$~:"\$_=q{$_};eval"x($l/4)};eval'

See the online test suite here.

Broken down

perl -e'
    $_=q{                      # store source code in $_
        print+(
            $l=($~=<>)=~ y///c # read STDIN into $~, assign length to $l
        )%4 ?                  # if length is a multiple of 4
             $~ :              # print $~
             "\$_=q{$_};eval"  # otherwise, print source code
             x($l/4)           # length/4 times
    };
    eval'                      # eval $_ to execute its contents
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 229 bytes

($RecursionLimit = Infinity; WriteString[$Output, If[Mod[StringLength[a = (If[(a = InputString[]) === EndOfFile, "", StringJoin["\n", a, #0[]]] & )[]], 4] == 1, ToString[#0, InputForm][], If[a == "", "", StringDrop[a, 1]]]]) & []

All of the whitespace is for the InputForm of the program to match its actual code.

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

Javascript ES6, 45 bytes

$=(_=prompt())=>_.length%4?_:`$=${$};$()`;$()

Extension of my 21-byte Bling Quine. Hope that mixing prompt and function output is allowed.

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

JavaScript, 33 bytes

f=(i,l=i.length)=>l%4?i:("f="+f).repeat(l/4)
  • +44 bytes
  • -25% bonus

Other solutions:

44 36 bytes

f=(i,l=i.length)=>l%4?i:("f="+f).repeat(!!l)

f=(i,l=i.length)=>l%4?i:l?("f="+f):i

38.5 bytes

f=(i,l=i.length)=>l%4?i:Array(l/4).fill("f="+f).join` `
  • +55 bytes
  • -25% bonus
  • -5% bonus
\$\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.