Napisz poliglotę, która wypisze nazwę języka

65

Twoim zadaniem jest napisanie programu, który będzie działał w jak największej liczbie języków, przy użyciu jak najmniejszej liczby znaków. Aby uniknąć trywialnych rozwiązań, program musi wydrukować nazwę języka, w którym został uruchomiony.

Punktacja

Twój program musi działać w co najmniej 5 językach. Wynik programu jest podawany jako:

(number of languages)1.5 / (length of program)

Najwyższy wynik wygrywa, nie wcześniej niż 10 dni po pierwszej ważnej odpowiedzi.

vsz
źródło
Czy użycie rozwiązania takiego jak print()Perl, Python, PHP, Processing i R byłoby uważane za trywialne, czy jest dopuszczalne?
Rob
3
Nie widzę z tym problemu. Trudność polegałaby na zmianie wejścia wydruku na język.
mjgpy3
Powinienem był przypisać większą wagę liczbie języków ... wydaje się, że wybór dokładnie 5 jest najbardziej optymalny. Zastanawiam się, ile języków znalazłoby się we wpisie zwycięzcy, gdyby wynik byłn * n / length
vsz
Też zamierzałem to zasugerować. Na podstawie udzielonych odpowiedzi nie sądzę, że poprawnie zinterpretowałem twoje pytanie.
Rob

Odpowiedzi:

39

Bash, C, C ++, Obj-C, Obj-C ++, Perl, PHP, Ruby, 183 znaków

wynik ~ 0,1236

W przypadku kodów C i C mam dług wobec @ baby-rabbit. Inne inspirowane są uznaniem, że wiele języków ma evalstwierdzenie, które niechętnie zaakceptują nieprawidłową składnię.

Wyświetla nazwę języka na standardowe wyjście. Czasami generuje wiele komunikatów o błędach przy standardowym błędzie, więc pomijaj je przy 2>/dev/nulluruchamianiu.

#if 0
'PHP<?/*';eval "print\$=?'Perl':'Ruby';echo Bash";exit
__END__
#endif
#include <stdio.h>
main(){puts(
#ifdef __OBJC__
"obj-"
#endif
"C"
#ifdef __cplusplus
"++"
#endif
);}//*/?>'

Wyjście rozwiązania php 'PHP'(łącznie z pojedynczymi cudzysłowami), które może nieco wyginać reguły.

Ostatnia edycja: 12 znaków z ogoloną spostrzeżeniu, że $=jest falsew Ruby, 60Perl, i print$=?...jest prawie na pewno błąd w bash. Ogoliłem jeszcze 7 z wglądu, test Perl / Ruby / Bash może teraz przejść do jednej instrukcji eval.

Jeśli reguły mogą tolerować więcej zgięć, przedstawię 8 języków, 43 znaki (wynik 0,5262)

print("phperluarscriptrubypythoncatebg13");

dla którego wyjście zawiera nazwę tłumacza php, perl, lua, rscript, ruby, python, cat, i rot13.

tłum
źródło
1
TI-Basic obsługuje ostatni; po prostu dodaj 6 znaków i zdobądźprint("phperluarscriptrubypythontibasicatebg13");
Timtech
1
@Timtech nie, TI-Basic używa tokenów Displub Output(lub text(, nie ma print(polecenia. Dołączenie łańcucha jako części wyrażenia o wartościach rzeczywistych powoduje ERR:INVALID SYNTAX, że nie wyświetla się on (nawet jako wartość zwracana). (Ponadto nie ma ;; zastosowania TI-Basic :)
AJMansfield
@AJMansfield Zbyt prawdziwe, jak mogłem zapomnieć:?
Timtech
12
Można zastąpić echo Bashz ps -ocomm= -p$$? Spowoduje to wyświetlenie nazwy powłoki przynajmniej dla bash, zsh, ksh, csh i tcsh, może innych.
Cyfrowa trauma
19

C, C ++, BF, BASH i Ruby; 280 znaków

Wynik to około 0,040

#include "stdio.h"
#define s "C"
#ifdef __cplusplus
#define s "C++"
#endif
#ifndef s
#"+++++++++[>++++++++++>+++++++++<<-]>>-.<++++.>-.++++++++.<----.>---.<+++++++.>---.++++++++.<<++++++++++.[-]"
if [ 1 == 2 ];then
puts "Ruby"
exit
fi
echo "BASH"
exit
end
#endif
main(){puts(s);}

Zauważ, że używam systemu Linux.

Kod jest uruchamiany lub kompilowany za pomocą następujących poleceń (nazwa pliku to test.c)

DO:

gcc test.c

Po uruchomieniu z ./a.outwyjściem jestC

C ++:

c++ test.c

Po uruchomieniu z ./a.outwyjściem jestC++

GRZMOTNĄĆ:

./test.c

Wyjścia: BASH

Rubin:

ruby test.c

Wyjścia: Ruby

BrainF ***:

Zweryfikowano przy użyciu:

Wyjścia: brainfuck

Zauważ, że jeśli używany jest debuger JS, należy usunąć dwa pierwsze znaki minus. Zostały one uwzględnione, aby zrównoważyć znaki plus w dosłowności łańcucha "C++". To był bardzo fajny projekt, pracuję nad dodaniem kolejnych języków.

Aby jeszcze bardziej wyjaśnić, oto specyfikacje mojego tłumacza / kompilatora:

  • wersja gcc 4.6.3

  • ruby 1.9.3p194 (wersja 2012-04-20 wersja 35410) [x86_64-linux]

  • GNU bash, wersja 4.2.24 (1) -release (x86_64-pc-linux-gnu)

DYGRESJA

Używając sztuczki @ baby-rabbit udało mi się rozszerzyć mój kod, aby był wykonywalny w 7 językach (dodano C-C i C-C ++). To nie jest moje rozwiązanie, ponieważ niektóre z nich skopiowałem, ale pomyślałem, że się pochwalę.

Aktualizacja 9.12 Dodano bieg SmallTalk z gnu-smalltalk!

SmallTalk, C, C ++, Objective-C, Objective-C ++, BASH, BF, Ruby; 384 znaki (Wynik: 0,059)

#if (a)
##(true) ifTrue: ['SmallTalk' printNl]
##(ObjectMemory quit)
#"+++++++++++[>++++++++++>+++++++++<<-]>>-.<++++.>-.++++++++.<----.>---.<+++++++.>---.++++++++.<<++++++++++.[-]"
if [ 1 == 2 ];then
puts 'Ruby'
exit
fi
echo 'BASH'
exit
end
=begin
#endif
#include "stdio.h"
main(){puts(
#ifdef __OBJC__
"Objective-"
#endif
"C"
#ifdef __cplusplus
"++"
#endif
);}
#ifdef b
=end
#endif

W powyższym kodzie należy zmienić nazwę pliku, aby utworzyć nazwę języka dla celu-c, obj-c ++, c oraz c ++.

mjgpy3
źródło
czy byłoby krótsze, gdybyś wyprowadzał brainf***?
tłum
Tak, wierzę.
mjgpy3
Powinieneś użyć if [ 1 = 2 ]zamiast if [ 1 == 2 ], ponieważ skrypty bez hashbangu są wykonywane przez sh, a nie bash. sh może, ale nie musi być bash, w Debianie jest to myślnik.
nyuszika7h
12

bash, c, c ++, obj-c, obj-c ++; 134 znaki; wynik = 0,083

#if x
echo "bash"
exit
#endif
#include <stdio.h>
int main(){puts(
#ifdef __OBJC__
"obj-"
#endif
"c"
#ifdef __cplusplus
"++"
#endif
);}

zmień nazwę pliku i uruchom / skompiluj jako:

  • plik sh.sh
  • Plik DW. c
  • cc plik.cpp
  • plik DW. m
  • plik cc.mm

(gdzie cc jest clang-421.10.42)

króliczek
źródło
+1, ponieważ wiele innych pozytywnych odpowiedzi zostało zainspirowanych przez Ciebie.
Kevin
11

Lua, Ruby, VimL, ​​Sed, Befunge (129 znaków; ~ 0,087 punktów)

Nie jestem pewien, czy to się liczy - część sed jest osadzona w linii shebang, co jest prawdopodobnie włamaniem do obejścia ograniczenia. Oznacza to również, że powinien on być uruchamiany jako plik wykonywalny, a nie bezpośrednio z sed.

Miałem szczęście, że wszystkie inne języki (sans Befunge) automagicznie ignorują linię shebang (chociaż najwyraźniej Ruby odmawia uruchomienia pliku, jeśli zawiera ona linię shebang, która nie zawiera w sobie łańcucha „ruby”).

#!sed sanava;s/.*/sed/;q;ruby
--"".to_i#>"egnufeB">:#,_@
if 0
then
if IO
then
puts"Ruby"
else
print"Lua"
end
else
echo"VimL"
end

Przykładowe użycie:

% lua tmp/glot.poly
Lua
% ruby tmp/glot.poly
Ruby
% ./tmp/glot.poly
sed
% cfunge tmp/glot.poly       # Requires Befunge-98
Befunge

:source tmp/glot.poly        # from vim
VimL                         # displayed as message
Robaczek świętojański
źródło
5
Wow, rozwiązanie, które nie obejmuje C
vsz
8

BF, Bash, Batch, C, vi (163 znaki; wynik ≈ .0686)

( <ESC>oznacza kod ASCII 27.)

rem (){ ((0));};true /*
rem ;goto(){ rem;}
rem ivi<ESC>ZZ'++++++++[>NUL ++++++++<NUL -]>NUL ++.++++.*/;main(){puts("C");}/*'
goto a
echo Bash
exit
:a
echo Batch
rem */

Przetestowałem to jako plik wsadowy w wersji COMMAND.COM w wersji MS-DOS 6.22. Domyślnie ten interpreter miesza wiersze kodu źródłowego z danymi wyjściowymi. Aby temu zapobiec, wykonaj echo offprzed uruchomieniem pliku wsadowego.

Aby wykonać kod vi, który przetestowałem tylko przy użyciu Vima, użyj następującego polecenia:

cat /dev/null > tmpfile && vi -s polyglot.sh tmpfile > /dev/null 2>&1 && cat tmpfile
Proszę wstać
źródło
1
Możesz użyć touch tmpfilelub : > tmpfilezamiast cat /dev/null > tmpfile.
nyuszika7h
5

bash, zsh, ksh, csh, tcsh, 15 znaków, wynik 0,745

Ten jest trochę rozciągnięty, ponieważ są to wszystkie powiązane języki, ale są różnice:

ps -ocomm= -p$$
Cyfrowa trauma
źródło
Co z deską rozdzielczą?
Elliot A.
4

Każda wersja Python, 18.37291 punktów

import sys
print('Python '+'.'.join(map(str,sys.version_info[:-2])))

Technicznie poprawne, jeśli weźmiesz pod uwagę wszystkie wersje języka Python w różnych językach. Obecnie istnieje 116 wersji Pythona, co moim zdaniem daje wynik około 18,37291.

(Rozumiem również, że jeśli nie jest to poprawna odpowiedź, to tylko dla zabawy)

EdgyNerd
źródło
wciąż dostajesz moje +1 tylko dla zabawy.
vsz
Czy można wydrukować pełny numer wersji? (To zmniejsza o 4 bajty i rozszerza możliwe wersje Pythona.)
A
Czy to w porządku? tio.run/##K6gsycjPM/7/…
A _
3

Bash, C, Gawk, Perl, vi (145 znaków; wynik ≈ .077)

( <BS>oznacza kod ASCII 8. <ESC>oznacza kod ASCII 27.)

#define echo//<BS><BS><BS>vi<ESC>ZZ
#define BEGIN A()
#define B\
{
echo Bash ;exit;
#define C\
}
BEGIN {printf(A=="A"?"Perl":"Gawk");exit;}
main(){puts("C");}

Aby wykonać kod vi, który przetestowałem tylko przy użyciu Vima, użyj tego polecenia:

cat /dev/null > tmpfile && vi -s polyglot.sh tmpfile > /dev/null 2>&1 && cat tmpfile
Proszę wstać
źródło
3

To jest tani wybór języków, ale oto:

CoffeeScript, JScript, Mozilla JavaScript (≈ JavaScript 1.3), ECMAScript Edition 5, ECMAScript Edition 3, 223 znaków, wynik ≈ 0,0501)

a="undefined"
x="ECMAScript 3"
if(Array.prototype.map)
 x="ECMAScript 5"
if(typeof CoffeeScript!=a)
 x="CoffeeScript"
if(typeof uneval!=a)
 x="Mozilla JavaScript"
if(typeof WScript!=a)
 WScript.echo("JScript")
else alert(x)
Peter Olson
źródło
5
JavaScript, JavaScript, JavaScript (≈ JavaScript), JavaScript, JavaScript, 263 znaków, (wynik ≈ 0). możesz też skrócić to a="undefined";if(typeof arguments!=a)...else if(typeof WScript!=a...oh i możesz też spróbować zagrać w golfa ....
Chłodzenie matematyki
@tryingToGetProgrammingStraight Umieszczenie wszystkiego w jednym wierszu w taki sposób nie jest poprawną składnią w CoffeeScript (który jest językiem innym niż JavaScript). Inne są dyskusyjne, ale ponieważ nie określono, jak różne muszą być języki, myślę, że różne implementacje mają różne określone zachowania, co pozwala traktować je jako osobne.
Peter Olson
Ja też mogę napisać komentarz multi-liniowy, jedynym golfa wydaje się być wykorzystywane opuszcza out {/ }/ ;... chodzi o to, aby wykorzystać aw celu uniknięcia ponownego wykorzystania "undefined", można również zrobić b=alerti potem b("this is also still just javascript"). w każdym razie The golden rule of CoffeeScript is: "It's just JavaScript"(z coffeescript.org ) możesz także użyć jquery, aby dodać szósty język ....
matematyki
1
@tryingToGetProgrammingStraight Dodawanie jQuery byłoby absurdalne, ponieważ jQuery jest biblioteką, a nie językiem. CoffeeScript zdecydowanie nie jest tym samym językiem, co ECMAScript. Definicja języka to zestaw skończonych ciągów znaków nad skończonym alfabetem. Zestaw ciągów znaków reprezentujących prawidłowe programy CoffeeScript nie jest taki sam jak zestaw ciągów znaków reprezentujących prawidłowy ECMAScript.
Peter Olson
1
Czy możesz to zrobić [].mapzamiast Array.prototype.map?
ETHprodukcje
3

Java, Lisp, Whitespace, Intercal, PHP, Befunge-98; wynik = .0189

To była pierwotnie odpowiedź na to .

 ;\\0"egnufeB">:#,_@SSSTTTSTTTL
;TL
;SSSSSTTSTSSSL
;TL
;SSSSSTTSTSSTL
;TL
;SSSSSTSTSTSSL
;TL
;SSSSSTTSSTSTL
;TL
;SSSSSTSTSSTTL
;TL
;SSSSSTTTSSSSL
;TL
;SSSSSTTSSSSTL
;TL
;SSSSSTTSSSTTL
;TL
;SSSSSTTSSTSTL
;SSL
;L
;L
;L
;public class H{ public static void main(String []a){System.out.println("JAVA");}}
;/*
(print "LISP")
;*/
;//<?php
; echo "PHP"
;//?>
;/*
#|
DO ,1 <- #8
DO ,1 SUB #1 <- #110
DO ,1 SUB #2 <- #32
DO ,1 SUB #3 <- #72
DO ,1 SUB #4 <- #136
DO ,1 SUB #5 <- #88
DO ,1 SUB #6 <- #136
PLEASE DO ,1 SUB #7 <- #64
DO ,1 SUB #8 <- #80
PLEASE READ OUT ,1
PLEASE NOTE |#
;*/
;// PLEASE GIVE UP
Juan Sebastian Lozano
źródło
To nie będzie działać w Javie; każda linia aż public class...spowoduje problem z kompilatorem.
Ypnypn
Interesujące ... Wyraźnie pamiętam testowanie tego w kompilatorze i to działa ... a może moja pamięć mnie zawodzi ...
Juan Sebastian Lozano
@Ypnypn Pamiętaj, że „T” jest tabulatorem, „S” to spacja, a „L” to przejście do wiersza w spacji, dlatego nie powoduje błędu kompilatora.
Juan Sebastian Lozano
O; to ma sens.
Ypnypn
3

Windows Batch, TI-Basic, Golf-Basic 84 , Quomplex i GTB 5 * 2/93 = 0,11

::¤Quomplex¤:"'*[]'":~"GTB":g;1:d`"GOLF-BASIC 84":g`1:"TI-BASIC":Lbl 1:End
echo Windows Batch

Jak to działa

Windows Batch był najłatwiejszy, ponieważ ::zaczyna się komentarz. Dość prosty do wdrożenia.

TI-Basic nie obsługuje małych liter ani odwrotnych znaków, co powoduje pominięcie instrukcji d`"GOLF-BASIC 84":g`1, które ewaluuje Golf-Basic, wyświetlanie wiadomości i przekazywanie do etykiety 1, gdzie jest natychmiast kończone. Jest to podobne do GTB, z poręcznym charakter wyświetlania ~. Nawiasem mówiąc, zostanie wstawiony ciąg bez wyświetlacza Ans. Jeśli po nim nie ma żadnych poleceń Display, Anszostaną wyświetlone (nie w tym przypadku).

Quomplex został wciągnięty na początku, ponieważ jego złożona składnia nie pozwala na pominięcie wielu elementów. Wszystko, co robi, to dodać "Quomplex"do wyniku, a następnie do opanowania programu ...

Opanowanie składni programowania

:"'*[]'"

Czysty geniusz. Quomplex ignoruje :i przyjmuje "'oraz '"jako łańcuchy, pozostawiając go do wyprowadzenia stosu i zginięcia w nieskończonej chwili pętli ( []). Tymczasem Golf-Basic i TI-Basic traktują całość "'*[]'"jako ciąg, ponieważ 'jest operatorem matematycznym, a nie ciągiem.

Timtech
źródło
Ściśle mówiąc, :oznacza etykietę w pliku wsadowym, a nie komentarz. Prawdą jest jednak, że nie wykonuje niczego samodzielnie.
Mark
@ Mark Prawda, ale jest ::(choć nadal jest to etykieta). Wolałbym go używać REM, zwłaszcza że jest to wymagane w TI-Basic.
Timtech
Racja - po prostu byłem pedantyczny. Ponadto +1 za użycie plików wsadowych. :-)
Mark
2

JScript, EcmaScript Edition 3, 5, 6, 2016, Węzeł, Mozilla JavaScript (wynik 34 0,1342)

Ta odpowiedź jest pierwotnie oparta na odpowiedzi Petera Olsona, ale minus CoffeeScript (ponieważ znaczące białe znaki języki mogą być okropne dla gry w golfa).

Dodałem także Node , ES6 i ES2016 i trochę poprawiłem kod, prawie trzykrotnie zwiększając pierwotny wynik.

$=this,y="EcmaScript ",x=$.module?"Node":$.uneval?"Mozilla JavaScript":"".padStart?y+2016:$.Map?y+6:[].map?y+5:y+3,($.WScript||$.alert)(x)
Chiru
źródło
2

16 języków, 348 bajtów, wynik: 0,183908046

#include <stdio.h>
#if 0
#replace "C(gcc)" "C(ecpp)"
#replace "C++(gcc)" "C++(ecpp)"
#endif
#ifdef __clang__
#define d 2
#elif __TINYC__
#define d 4
#else
#define d 0
#endif // rk:start print: "rk" \
ps -ocomm= -p$$; exit;
int x=sizeof('a')%2+d;char*arr[]={"C(gcc)","C++(gcc)","C(clang)","C++(clang)","C(tcc)"};int main(){puts(arr[x]);}

Działa to w C (gcc), C ++ (gcc), C (ecpp), C ++ (ecpp), C (clang), C ++ (clang), C (tcc), sh, dash, bash, zsh, ksh, csh, tcsh, rk i SIL.

MD XF
źródło
0

JScript, EcmaScript Edition 3, 5, 6, 2016, 2017, Węzeł, Mozilla JavaScript (wynik = .174193548387), CoffeeScript (ponieważ znaczące białe znaki języki mogą być okropne dla gry w golfa).

$=this,y="EcmaScript ",($.WScript||alert)(x=Object.values?y+2017:$.module?"Node":$.uneval?"Mozilla JavaScript":[].includes?y+2016:$.Map?y+6:[].map?y+5:y+3)
użytkownik75200
źródło