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

14 Answers 14

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\$
0
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\$
3
  • \$\begingroup\$ G` is cool! It seems more legit than a simple Q command. \$\endgroup\$ Dec 11, 2015 at 13:17
  • \$\begingroup\$ Seems less legit to me, seeing as how it requires file I/O. \$\endgroup\$
    – quintopia
    Dec 11, 2015 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\$ Dec 11, 2015 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
  • 2
    \$\begingroup\$ Doesn't this violate the rule that "You may not read the source code from a file"? \$\endgroup\$ Dec 10, 2015 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, 2015 at 11:18
2
\$\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\$
8
  • 6
    \$\begingroup\$ In a quine challenge, I believe you cannot read the program source. \$\endgroup\$ Dec 10, 2015 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, 2015 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\$ Dec 10, 2015 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\$
    – user45941
    Dec 11, 2015 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\$ Dec 11, 2015 at 8:17
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\$
1
  • \$\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, 2015 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\$
1
\$\begingroup\$

Python 3.8 (pre-release), 71 bytes -30% = 49.7

exec(a:="s=len(t:=input());print(*s%4and[t]or s//4*['exec(a:=%r)'%a])")

Try it online!

\$\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\$
0
\$\begingroup\$

Zsh, 78 bytes

s='s=\47%s\47
0()printf $s $s
$[$#1&3]||<<<$1'
0()printf $s $s
$[$#1&3]||<<<$1

Try it online!

Uses &3 instead of %4 so the % doesn't get interpreted by printf.

The bonus could be added with repeat $[$#1/4] before the printf in both places, but unfortunately it gives a higher score (\$ 75\% \times 110 = 82.5 \$).

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

Excel, 204 bytes - 30% = 142.8 score

=LET(a,LEN(A1),c,CHAR(34),q,"=LET(a,LEN(A1),c,CHAR(34),q,#,IF(MOD(a,4)=0,TRIM(REPT(SUBSTITUTE(q,CHAR(35),c&q&c),a/4)),LEFT(A1,1))) ",IF(MOD(a,4)=0,TRIM(REPT(SUBSTITUTE(q,CHAR(35),c&q&c),a/4)),LEFT(A1,1)))

Link to Spreadsheet

2nd Place, 191 bytes - 25% = 143.25 score

=LET(a,LEN(A1),c,CHAR(34),q,"=LET(a,LEN(A1),c,CHAR(34),q,#,IF(MOD(a,4)=0,REPT(SUBSTITUTE(q,CHAR(35),c&q&c),a/4),LEFT(A1,1)))",IF(MOD(a,4)=0,REPT(SUBSTITUTE(q,CHAR(35),c&q&c),a/4),LEFT(A1,1)))

3rd Place, 179 bytes

=LET(a,LEN(A1),c,CHAR(34),q,"=LET(a,LEN(A1),c,CHAR(34),q,#,IF(a*(MOD(a,4)=0),SUBSTITUTE(q,CHAR(35),c&q&c),left(A1,1)))",IF(a*(MOD(a,4)=0),SUBSTITUTE(q,CHAR(35),c&q&c),LEFT(A1,1)))

Best Cheesy Answer, 59 byte - 25% = 44.25 score

=LET(a,LEN(A1),IF(MOD(a,4)=0,REPT(FORMULATEXT(B8),a/4),A1))
\$\endgroup\$
0
\$\begingroup\$

Vyxal, 38 - 25% = 28.5 bytes

`?DL4%[|[$:q$+$L4/*`?DL4%[|[$:q$+$L4/*

Try it Online!

`...`                      # Source code in string
     ?                     # Grab input
      D                    # Triple
       L4%                 # If length is (not) divisible by 4
          [|               # Do nothing, otherwise
            L0>[           # If length is positive
                $          # Swap (to get source-code string)
                 :q$+      # Standard quine - duplicate, uneval, swap, concatenate
                     $     # Swap to get original input
                      L4/  # Length / 4
                         * # (Source code) that many times

Trying to get the bonus is sadly longer.

\$\endgroup\$

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.