Seriously, GolfScript, CJam, or Pyth?

56

3

Some time ago, the following question was asked: GolfScript, CJam, or Pyth? Based on the title only, I thought that it would be a very nice challenge, but unfortunately, it turned out to be a question asking for tips. Here is the challenge I wanted to read:

Who said golfing languages were not used in the Real World? As everybody knows, the ratio of bugs per line of code is the same independently of the programming language being used, so there is a clear opportunity to reduce debugging and maintenance costs with those languages. Your company finally saw the light and decided to use Golfscript, CJam and Pyth to develop its products.

Unfortunately, after a couple of months, your hard drives are cluttered with snippets of code and you don't even know which ones are written in which languages (you even suspect some of your programmers of using Perl).

You must write a tool to detect which of CJam, Golfscript or Pyth is the language in which a program is written. The situation is critical, you can use any language you want, but please keep it short (data storage is expensive: the more bytes we use, the more it costs).

General

  • Shortest code win
  • Standard loopholes, etc.
  • Don't use an online interpreter
  • You can write a function or a program
  • You can use eval to detect your own language

Input

  • Your input is taken from the standard input stream or as a string
  • Input contains only ASCII printable characters and linefeeds
  • The size of the input is up to 256 bytes long

Output

  • Output is printed to output stream or returned as a sequence of strings/symbols
  • If the input is without doubt a valid X program, print or return X, X ∈ {CJam, Pyth, Golfscript}

    Remark: "without a doubt" does not mean that you are allowed to answer with a dumb analyzer that consistently fails to detect any language. For Pyth, I expect Simple Programs to be recognized (but no hardcoding). The same goes for CJam (cheat sheet, examples) and Golfscript (examples). The previous links point to each language's specifications. If you use a fuzzy/bayesian approach, "without a doubt" means with a high-level of confidence (you score 99% with your classification, for example). See below for the actual test suite.

  • If the input is valid in multiple languages, each detected language should be printed/returned. When printed, there must be a separator between multiple outputs (e.g. space, newline, comma...).

  • The order in which languages are tried does not matter
  • I do not care about case (CJam, cjam, CJAM, SPAM) [1]
  • If none of the above language is detected, print "Probably Perl". Thanks to this comment from mbomb007, in the above case you can also output "Seriously" for a penalty of 4 bytes (the difference between both strings).

[1] Just to be clear, SPAM is invalid

Examples

  • Input

    "Crime predicted: --
    Calling: 1--555-
    
    "30*{_5<{iAa*:mr}&}/
    
  • Output (example of multiple return values)

    ["Golfscript", "Cjam"]
    
  • Input

    3
    
  • Output (example on standard output)

    golfscript
    cjam
    pyth
    
  • Input

    if {} aazd
    
  • Output

    Probably Perl
    

In the last case, the input program produces an error With All Three online interpreters.

Scoring, winning criterion

Shortest code win. Add 4 bytes if you output "Seriously". Then, apply bonuses.

Failing tests

The following are snippets that must not be recognized as any of the three languages above.

One-liners (i.e. one entry per line)
$^X=~/([a-z]+)[^\/]+$/;print$1,$/
<>;map($s-=(-1)**$_/(2*$_-1),1..$_),$s=!print$s,$/for<>
((THIS IS LISP HAIKU) (TRULY THIS IS LISP HAIKU) (THIS IS LISP HAIKU))
(format t"~@(~{~R~^, ~}~).~%~:*~@(~{~:R~^, ~}~)."(loop for i to 99 collect(1+ i)))
print sum(ord(c) for c in 'Happy new year to you!')
Brainfuck
>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
++++++++++++++++++++++++++++++++++++++++++++++++.
-----------------.
++++++++.
+++++.
--------.
+++++++++++++++.
------------------.
++++++++.
Perl
@list=( "aaaa", 
        "aaaaaaaa", 
        "aaaaaaaaaaaaaaa", 
        "aaaaaaaaaaaaaaaa", 
        "aaaaaaaaaaaaaaaaaaaaaaa", 
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

while (@list) {
    for($i=0;$i<6;$i++){
        print length($list[$i])." ";
    }
    print "\n";
}
Fish
#ifndef __linux
#include "x.h"
#define X/*\
a=1 set -e
+++++++++++++++++++++_+++++++++++++....Hello World!?:Q:
#endif
    echo "Hello, World!"
    int m(){}

Basic test suite

Those are tests which must pass. Belows are one-liners for each language where your program must detect the language it is being written in (I did not check which of those are polyglot).

Pyth

*2Q
FNrZTN
FNrZhTN
FNUhTN
VhTN
FNr1hQN
=N5N
K5K
K1FNr1hQ=K*KN
K1FNr1hQ=K*KNK
K1FNr1hQ=K*KN;K
DhZK*3ZRK
L?b*bytb1yQ
A(Z1)VQHA(H+HG

Golfscript

;'2706 410'~{.@\%.}do;
;''6666,-2%{2+.2/@*\/10.3??2*+}*`50<~\;
'Hello, world!'
1 2 [\]

CJam

"Hello, world"
{`"_~"}_~
"`_~"`_~
T1{_2$+}A*]`
{__'`>\'x>26*2-*-}/
Y38#
N/s:X,8-,{X>9<__{'a<},,\4%{'Z>},,*I={4=}{;}?}/

Silver bonus: byte-count * 0.6

All previous tests must pass, as well as the following one-liners. All those snippets are taken from actual CodeGolf answers.

Pyth

VzJ:zZhZpkJ~Zhy}rJ0-G"aeoui
Vzjdm?@zd}N,dt-lzd\ Uz
jd.iSQs*RtQ,\?":0
rsXOtQmO*-GJ"aeiou"J/Q2*%Q2O"hy"4
VhQIq`N_`NN
s["$$\\varphi=1+"*Q"\cfrac1{1+"\\<\dQ"dots"*Q\}"$$
@c"weak trick fair"d-!JlfhT-M.:us_cG.u+NYtKrH7-52hK.zU52 2>J26

Golfscript

);:|;{0):0;|$:§-1%" - "§" = ""0"4$~§~-+-4>:|n|6174`=!}do"Iterations: "0"."
'-+,/'{)))))}%
4:echo(2+2);
#undef X;A!"$%&'()*+-[,.]/0123456789:<=>?@BCDEFGHIJKLMNOPQRSTUVWYZ\^_`abcghijklmopqrstvwxyz{|}~
{`),32>^.}.~
"126,32>''+".~\-'.~\-"'-
"),@`^^32>#.~".~
...[[]]{{}}&%%++++5i
  *++..0011125::::;;;?bbbbcccc{}
"This program wasn't written in "o"GolfScript"", it was built for ""CJam"oo"!"

CJam

"Q"c("ASSW"1$("aRD"(((T1
%\@_@){;_0}*__*)\15
"This program wasn't written in "o"GolfScript"", it was built for ""CJam"oo"!"
"P2"1e3K51_,1>K*$K*~]N*
li__,\mf:i2m1+:*/fb:+
ri:B__(^2/):G/,{_BBG/@-(#G@*G(B2/*+*}/]:+
{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~
[S'-26*N]:Z[S'|:PS24*PN]:RR'(PS5*qi:XD=X0<-X2%2*+:Y[" ^ "_" > ""(O)"" - "__]=S8*Y[" ^ ""   "" < ""(O)"" - "__]=S5*P')NRRXD=[SPS7*'oA*S7*PN]:QR?Y[[SPS5*'oSC*'oS5*PN]:T_R[SPS7*'oS8*'oS7*PN]RRR]=QY2=TR?RRZ
li4H#+2bW%32<2b
q~:R100:H*\d:T/i){R-H*HT-/m]}6*_H)<*
"JamesBdo,"YZ+/)BA*c+Y*Y%:BS@SB)))[JW:Z____)ci+*]U*

Gold bonus: previous-score * 0.8

Pyth

Compare
jdm@cd)._-FQcj"
is
equal greater less
to than
"Qb
Snowman
M@GCHgc"  ___

  ___
   _"bhzgc" (_*_)
 _===_
 .....
  /_\\"bhzs[g"  \ "@z4\(g"-.oO"@z2g" ,._"@z1g"-.oO"@z3\)g"  / "@z5)s[g" < /"@z4\(gc"   
 : 
] [
> <"b@z6\)g" > \\"@z5)++" ("gc"   
 : 
\" \"
___"bez\)

CJam

Big
rri:Hri:Vri:Q[q~]3/_Qa3*a+_|$W%:Pf{\a#}:AH/:B0ff*
P,,[AHAW%HBz:+_W%V\V]2/
ff{~@@f=/::|1#}0Ua4*t:R;
P0f<
V{H{BI=J=_2$=
0R{"I>! I+V<J>! J+H<"4/+4/z{~~}%:&1$*\)}%);2$-|t
}fJ}fI
[P,{_La#\1$0t1$f-}*;;]
{:TR=2/~\~V\-,>\f{\_3$=@~H\-,>{Tt}/t}~}/
:~Pf=:~
~]S*N
Snowman
q:Q;SS"
 _===_,___
 ....., _
  /_\,___
 (_*_)"',/0{Q=~(=}:G~N" \ "4G'(".oO-"_2G",._ "1G@3G')" / "5GN"< / "4G'(" : ] [> <   "3/6G')"> \ "5GNS'(" : \" \"___   "3/7G')

Golfscript

Lorem Ipsum
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet est ut sem commodo scelerisque. Sed ut ultricies enim. Nam eget lectus suscipit, gravida turpis a, volutpat tellus. Cras efficitur luctus neque, at semper massa condimentum at posuere.
Digital clock
:*{32' _':$@'14'{?~!=}:&~32}%n*{:x' |':|\'1237'&$x'017'&|x'56'&}%n*{:x|\'134579'&$x'147'&|x'2'&}%
Happy birthday
4,{"Happy Birthday "["To You""Dear GolfScript"]@2==n}%
Farey sequence
~:c[,{){.}c(*}%.c/zip{+}*]zip{~{.@\%.}do;1=},{~<},{~\10c?*\/}${'/'*}%', '*'F'c`+' = {0/1, '+\', 1/1}'

coredump

Posted 2015-09-23T15:13:00.757

Reputation: 6 292

54From the title, I was hoping this included a new esoteric language called "Seriously". – mbomb007 – 2015-09-23T15:21:45.700

1Are HTTP requests allowed to check with the online interpreter? – Downgoat – 2015-09-23T15:22:43.580

@vihan NO. No network trick. – coredump – 2015-09-23T15:25:16.037

17@mbomb007 Seriously: a language that runs result of the source interpreted in Golfscript as Pyth, then pushes the newline separated values onto a CJam stack and finally outputs to STDOUT from there. Twice as easy to use as perl :^) – FryAmTheEggman – 2015-09-23T15:27:01.737

3@mbomb007 I feel your disappointment. May I suggest to ask your own question? "Not so long ago, the following question was asked..." – coredump – 2015-09-23T15:58:09.283

2>

  • Your first example is also valid GolfScript. 2. I expect Simple Programs to be recognized. Does that mean our submission has to work only for those examples?
  • < – Dennis – 2015-09-23T16:20:05.843

    @Dennis 1. I encountered "unexpected token" using http://copy.sh/golfscript/; is ther anything wrong with my approach or the interpreter? is there another interpreter I should use? 2. At least those examples. If the answer only works with them, that's ok. Hard-coding the answers feels cheaty, but I don't have an effective criterion to counter that. I guess an answer which is more complete will have more upvotes, but for the byte count criterion, those examples are enough.

    – coredump – 2015-09-23T16:28:52.147

    2

    >

  • copy.sh's interpreter deviates from the spec in many aspects. The first example works using the official Ruby interpreter or http://golfscript.apphb.com/. 2. In that case, I'd recommend including all test cases a submission has to pass in the question body.
  • – Dennis – 2015-09-23T16:33:38.403

    @FryAmTheEggman And if the Seriously program encounters a syntax error during any stage, it tries to interpret that stage as Perl instead. :P LET'S MAKE IT! Combining the interpreters, though... – mbomb007 – 2015-09-23T17:22:32.787

    3Some test cases that aren't in the language are needed. – isaacg – 2015-09-23T20:26:33.660

    32And this, my friends, is why shebangs were invented. – primo – 2015-09-25T08:29:40.130

    6I will give a 150 rep bounty to the first solution that is eligible for the gold bonus and validates inputs based on pattern matching, rather than my simple solution of running the programs through the interpreters. – Mego – 2015-10-31T20:21:36.460

    1"I did not check which of those are polyglot." If so then how do we know whether our solution is complying with "If the input is valid in multiple languages, each detected language should be printed/returned."? – Martin Ender – 2016-11-24T12:40:11.197

    1The set of falsy test cases also contradicts that rule. I haven't checked all of them but most of them are absolutely valid GolfScript programs (there aren't many ways to create a syntax error in GolfScript). If we shouldn't just check the syntax of the program, what exactly determines whether a program is "valid" in a language or not? – Martin Ender – 2016-11-24T12:48:13.713

    @MartinEnder Thanks, I'll look at this. – coredump – 2016-11-24T12:52:25.797

    1I think this challenge needs to better define what counts as a valid program in each language (especially given that GolfScript and CJam share a number of primitives). In many cases, the program can run in a given language, but it'd be insane to write it like that. – None – 2017-01-26T20:54:06.540

    1@ais523 It's clear based on the test cases that a valid program exits without errors (aka exit code 0). All of the test cases cause errors when run in a different language than intended. While it wouldn't hurt to add that specification to the challenge, it's not unclear now. – Mego – 2017-01-26T21:20:02.717

    @Mego: At least one of the programs is a polyglot, and appears in both the GolfScript and CJam sections; additionally, at least one of the Pyth testcases runs without error in GolfScript.

    – None – 2017-01-26T21:23:08.287

    I'm pretty sure there's a language called Seriously now. – CalculatorFeline – 2017-06-19T23:21:55.990

    @CalculatorFeline Yes indeed. But there is no answer to this challenge written in "Seriously", yet.

    – coredump – 2017-06-20T07:11:42.063

    Answers

    2

    Ruby, (135 + 4) * 0.6 * 0.8 = 66.72

    This runs on Windows and I'm too tired to shorten it by running on Unix.

    (a=[%w(javaw -jar cjam),%w(python pyth),%w(rubyw golfscript)].map{|c|c[-1]if system(*c,?f,'> NUL','2>','NUL')}-[nil])==[]?'Seriously':a
    

    I did these things but I'm not sure if they're allowed:

    • Rename cjam-[version].jar to cjam, pyth.py to pyth, golfscript.rb to golfscript.
    • Read from file f instead of getting input. (Add IO.write(?f,gets); to the beginning to fix that, and the new length is (153 + 4) * 0.6 * 0.8 = 75.36)

    RShields

    Posted 2015-09-23T15:13:00.757

    Reputation: 136

    Unfortunately, I can't test it (a combination of Windows and a lack of time). It looks good and your score is lower, so I am moving the checkmark. – coredump – 2018-04-26T04:30:45.420

    39

    Python 2, 332 * 0.6 * 0.8 = 159.36

    import os
    from subprocess import*
    from tempfile import*
    f,n,a=NamedTemporaryFile(delete=0),open(os.devnull,'w'),''
    f.write(os.read(0,256))
    f.close()
    for l in["CJam","java","-jar","cjam.jar"],["Pyth","./pyth.py"],["Golfscript","./golfscript.rb"]:a+=(l[0]+' ')*(call(args=l[1:]+[f.name],stdout=n,stderr=n)>0)
    print a or'Probably Perl'
    

    As far as I'm aware, this is within the rules. Requires the Pyth, CJam, and Golfscript interpreters (pyth.py, cjam.jar, and golfscript.rb) in the current directory, and Python 3, Java, and Ruby installed. Simple test: try running the program. If it returns with 0, we're good. If not, it's invalid. A named temporary file (e.g. a file created in $TMP) is created to hold the program, since CJam doesn't have a script option. The delete=False flag is necessary to prevent the file from being deleted when it is closed (the OS will take care of it for us). The file has to be closed before attempting to read from it (though manually flushing the file should also work, but this is simpler). stdout and stderr are redirected to /dev/null to suppress output/errors (note that this makes it only work on *NIX systems).

    Extra fun: try running the given code in all 4 languages, to see what we get:

    import sys
    from subprocess import*
    from tempfile import*
    c=["Cjam","java","-jar","cjam.jar"]
    p=["Pyth","./pyth.py"]
    g=["Golfscript","./golfscript.rb"]
    e=["Perl","perl"]
    f=NamedTemporaryFile(delete=False)
    s=sys.stdin.read()
    f.write(s)
    f.close()
    n=open('/dev/null','w+')
    a=''
    for l in [c,p,g,e]:
        try:
            print '%s: %s'%(l[0],check_output(args=l[1:]+[f.name],stderr=n))
        except:
            continue
    n.close()
    

    Mego

    Posted 2015-09-23T15:13:00.757

    Reputation: 32 998

    11+1 Nice answer. And it only requires 6 interpreters to run, well done ;-) – coredump – 2015-10-16T18:00:49.143

    1bash, Python 2, Python 3, Ruby, Java, CJam, Pyth, Golfscript - I count 8. – Mego – 2015-10-16T18:25:57.200

    2That's right. And with the right input file, it can even wipe your home directory. Anyway, this is a valid approach, I don't mind. – coredump – 2015-10-16T18:40:58.923

    Just let's hope you get no programs with endless loops, or returning non-zero. – Paŭlo Ebermann – 2015-10-17T22:41:13.307

    @Mego if a program itself fails for some reason (like when opening a file which does not exist – or when it is expecting arguments, which I suspect might happen more often for actually productively used programs), it should return a non-zero value according to that decade-old standard. This doesn't mean it doesn't belong to that language. (It might be none of the test cases are actually of that type, though.) Another case might be waiting for input, like a cat program ... maybe you should at least try to redirect /dev/null also to the input? – Paŭlo Ebermann – 2015-10-17T23:04:07.630

    You can golf another 12 chars by moving the values of c,p,g into the for statement. – Matthias Urlichs – 2016-02-14T06:50:17.030

    Do you need the continue? i.e. can you replace it with a 1? It seems to be at the end anyway. – Rɪᴋᴇʀ – 2016-02-26T22:16:50.893

    @RikerW That version was for extra fun, and is not 100% golfed. – Mego – 2016-02-26T22:19:55.210

    How is this not a violation of the third rule, no online interpreters. – None – 2016-11-10T21:37:38.403

    @GregTourville Because it doesn't rely on any online interpreters - it requires the interpreters to be locally present. – Mego – 2016-11-10T21:38:02.837

    That is interpreting the question too literally (common loopholes); an online interpreter and offline interpreter are effectively the same, it is not hosted by your program. – None – 2016-11-10T21:38:45.997

    @GregTourville I disagree, and so does the challenge author. My understanding is, online interpreters were disallowed to prevent attempts at exploiting this loophole.

    – Mego – 2016-11-13T12:53:39.863