Quat. Quine + Cat

23

2

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.

Bassdrop Cumberwubwubwub

Posted 2015-12-10T14:09:02.977

Reputation: 5 707

Can the input have multiple lines? – LegionMammal978 – 2015-12-10T23:14:34.213

@LegionMammal978 Ofcourse, let \n be the new line character, for 1 byte of input – Bassdrop Cumberwubwubwub – 2015-12-11T08:36:55.617

Okay, it just complicates input in my language, which must be read one line at a time. – LegionMammal978 – 2015-12-11T11:20:42.723

Are built-ins for quines allowed? (see: Seriously)

– Addison Crump – 2015-12-11T11:48:25.137

@FlagAsSpam I don't mind, but I think a meta-post is more appropriate here. – Bassdrop Cumberwubwubwub – 2015-12-11T12:16:44.050

@Bas I meant for your question, not in general. But okie den. – Addison Crump – 2015-12-11T12:17:50.297

@FlagAsSpam The OP of What counts as a proper quine? says "Clearly, any quine in HQ9+ or a related language is not a proper quine," and I don't see any contention over that point in the answers. I'm pretty sure I've seen that same point made in other posts.

– ThisSuitIsBlackNot – 2015-12-11T15:45:10.300

Is there any maximum input size we have to support? (I.e. do we have to buffer all 5 gigabytes of input until deciding whether to output them or the own source code?) – Paŭlo Ebermann – 2015-12-12T10:34:40.647

Answers

8

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 ]:\.

Martin Ender

Posted 2015-12-10T14:09:02.977

Reputation: 184 808

4

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.

quintopia

Posted 2015-12-10T14:09:02.977

Reputation: 3 899

6In a [tag:quine] challenge, I believe you cannot read the program source. – Conor O'Brien – 2015-12-10T20:32:04.687

3The 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" – quintopia – 2015-12-10T20:38:25.100

4I 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". – Martin Ender – 2015-12-10T23:35:56.980

2It doesn't say "don't use quining built-ins"... And not using built-ins is not an accepted standard loophole – quintopia – 2015-12-11T00:59:25.177

4Q 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. – Mego – 2015-12-11T02:25:15.510

3I 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. – Martin Ender – 2015-12-11T08:17:15.543

Hmm. I think when I tested empty input in the REPL, it actually gave it a newline, so it looked empty... Or something like that. – quintopia – 2015-12-11T13:19:30.147

@MartinBüttner Seriously is a valid programming language by our definition, unlike HQ9+. I don't know why Mario Golf isn't more popular; I think it's neat. The main difference I can see is that Q isn't just a built-in one-byte quine; it's also the simplest way to do recursion in functions. – Mego – 2015-12-23T04:09:20.637

2

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]

FryAmTheEggman

Posted 2015-12-10T14:09:02.977

Reputation: 16 206

2

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

Lord Yuuma

Posted 2015-12-10T14:09:02.977

Reputation: 587

2Doesn't this violate the rule that "You may not read the source code from a file"? – ThisSuitIsBlackNot – 2015-12-10T20:36:40.270

@ThisSuitIsBlackNot you're right... guess I'll have to look for a non-cheating Quine in Elisp – Lord Yuuma – 2015-12-11T11:18:26.223

2

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.

Addison Crump

Posted 2015-12-10T14:09:02.977

Reputation: 10 763

G` is cool! It seems more legit than a simple Q command. – Conor O'Brien – 2015-12-11T13:17:07.187

Seems less legit to me, seeing as how it requires file I/O. – quintopia – 2015-12-11T13:42:53.617

@CᴏɴᴏʀO'Bʀɪᴇɴ Quintopia is right - just because I get the file reference doesn't mean it's any better. :P – Addison Crump – 2015-12-11T16:39:47.543

1

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

ThisSuitIsBlackNot

Posted 2015-12-10T14:09:02.977

Reputation: 1 050

1

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.

jrich

Posted 2015-12-10T14:09:02.977

Reputation: 3 898

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 ?:. – Neil – 2015-12-11T00:29:51.517

0

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

ericw31415

Posted 2015-12-10T14:09:02.977

Reputation: 2 229

0

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.

LegionMammal978

Posted 2015-12-10T14:09:02.977

Reputation: 15 731

0

Javascript ES6, 45 bytes

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

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

Mama Fun Roll

Posted 2015-12-10T14:09:02.977

Reputation: 7 234