Rileva quale linguaggio di programmazione è uno snippet


23

La tua sfida è prendere un po 'di codice sorgente come input e output in quale linguaggio di programmazione è scritto.

Ad esempio, potresti avere l'input

class A{public static void main(String[]a){System.out.println("Hello, World!");}}

E uscita

Java

I tuoi due obiettivi principali sono la diversità (quanti linguaggi di programmazione riesci a rilevare) e la precisione (quanto sei bravo a rilevare questi linguaggi).

Per i poliglotti (programmi validi in più di una lingua), puoi decidere cosa fare. Potresti semplicemente generare la lingua che il tuo programma ritiene sia più probabile, oppure potresti generare un errore o potresti generare una serie di possibili scelte (che probabilmente otterrebbero più voti di un semplice errore!).

Questo è un , perché sarebbe molto difficile specificare un diverso criterio obiettivo vincente. Votanti, vota per quante lingue è in grado di rilevare e quanto è preciso.


Questo è impossibile, la causa print("")può essere utilizzata in molte lingue.
Ismael Miguel,

1
Con la tua modifica, ora sembra più possibile.
Ismael Miguel,

4
Che dire delle lingue valide per OGNI input? Come gli spazi bianchi. Questa frase è un programma di spazi bianchi valido. Tutta questa pagina è un programma di spazi bianchi valido.
Ismael Miguel,

1
L'ingresso è garantito per essere un programma valido? Come alcuni input potrebbe essere class A{public static void main(String[]a){System.println.out("Hello, World!");}}che non è valido.
Gaurang Tandon,

1
O allo stesso modo l'input HTML inizierà sempre con <!DOCTYPE html>seguito dal <html>, <body>e altri tag (like meta) nel loro ordine corretto?
Gaurang Tandon,

Risposte:


18

234 formati di testo - Unix Shell

(non tutte queste lingue - ho bisogno di contarle attentamente)

file $1

Esito a pubblicare questa risposta un po 'intelligente-a $$, ma non vedo nulla nelle regole che lo vietano e l' fileutilità della shell fa davvero un buon lavoro. per esempio:

$ file golfscript.rb 
golfscript.rb: Ruby module source, ASCII text
$ file template.c 
template.c: ASCII C program text
$ file adams.sh
adams.sh: Bourne-Again shell script, ASCII text executable
$ 

Inoltre è possibile utilizzare l' -kopzione per "continuare" durante il test di un poliglotta:

 -k, --keep-going
         Don't stop at the first match, keep going.  Subsequent matches
         will be have the string ‘\012- ’ prepended.  (If you want a new‐
         line, see the -r option.)

Inoltre, l' -lopzione ti darà un'idea di quanto sia buono l'algoritmo per le diverse lingue:

$ file -l | guscio grep
sconosciuto, 0: Attenzione: usando il normale file magico `/ etc / magic '
Forza = 280: testo dell'archivio shell [application / octet-stream]
Forza = 250: eseguibile del testo dello script della shell Tenex C [text / x-shellscript]
Forza = 250: eseguibile del testo dello script della shell Bourne-Again [text / x-shellscript]
Forza = 240: eseguibile del testo dello script zsh di Paul Falstad [text / x-shellscript]
Forza = 240: eseguibile del testo dello script ash di Neil Brown [text / x-shellscript]
Forza = 230: eseguibile testo script di ae di Neil Brown [text / x-shellscript]
Forza = 210: eseguibile del testo dello script della shell Tenex C [text / x-shellscript]
Forza = 210: eseguibile del testo dello script della shell Bourne-Again [text / x-shellscript]
Forza = 190: eseguibile del testo dello script della shell Tenex C [text / x-shellscript]
Forza = 190: eseguibile del testo dello script della shell Bourne-Again [text / x-shellscript]
Forza = 180: eseguibile del testo dello script zsh di Paul Falstad [text / x-shellscript]
Forza = 150: eseguibile del testo dello script della shell Tenex C [text / x-shellscript]
Forza = 150: eseguibile del testo dello script della shell Bourne-Again [text / x-shellscript]
Forza = 140: eseguibile del testo dello script di shell C [text / x-shellscript]
Forza = 140: eseguibile del testo dello script della shell Korn [text / x-shellscript]
Forza = 140: eseguibile del testo dello script zsh di Paul Falstad [text / x-shellscript]
Forza = 130: eseguibile del testo dello script della shell POSIX [text / x-shellscript]
Forza = 130: Eseguibile testo script di shell 9 rc piano []
$ 

Questo è file-5.09(su Ubuntu 12.04)


Questo in realtà funziona abbastanza bene su un poliglotta in 16 lingue - gist.github.com/riking/9088817
Riking

Si potrebbe anche tagliare fuori l'uomo medio e di evitare il guscio del tutto: ln -s /usr/bin/file /usr/local/bin/myspecialtool. Se la tua risposta conta, allora non conta altrettanto? (Non preoccuparti, non sono serio.)
hvd,

2
Sembra una scappatoia standard, ovvero delegare la soluzione al programma esistente.
Vi.

10

Bash: circa 50 35 byte per lingua compilabile

Il trucco è solo compilare, quindi non devi preoccuparti di collegare errori da librerie mancanti, ed è più indulgente se hai solo frammenti di codice.

Grazie a Shahbaz per le forme più brevi!

gcc -c $1 && (echo C; exit 0)
g++ -c $1 && (echo C++; exit 0)
gpc -c $1 && (echo Pascal; exit 0)
gfortran -c $1 && (echo Fortran; exit 0)

eccetera...


Dato che menzioni il numero di byte per lingua compilabile, potresti essere interessato a righe come:gcc -c $1 && (echo C; exit 0)
Shahbaz,

Grazie, non sono molto bravo a spremere davvero il codice!

Sicuro. Il &&e ||in bash sono davvero utili e aiutano a ripulire molto il codice. Non sono affatto usati per l'offuscamento, quindi faresti bene a impararli.
Shahbaz,

2
Puoi anche passare -fsyntax-onlya controllare solo la sintassi e saltare la compilazione effettiva.
peppe,

7

18 linguaggi di programmazione, 1002 byte, precisione: test da soli :)

(sì, so che questo non è un codice golf, ma per divertimento)

Il programma cerca frammenti di codice iconici, i controlli sono ordinati in modo che i controlli più chiari siano nella parte superiore e i linguaggi di programmazione incorporati in altri linguaggi di programmazione siano inferiori (ad esempio HTML in PHP).

Questo ovviamente fallisce per programmi come System.out.println('<?php');

t = (p) ->
    h = (x) -> -1 != p.indexOf x
    s = (x) -> 0 == p.indexOf x

    if h "⍵" then "APL"
    else if h "<?php" then "PHP"
    else if h("<?xml") and h "<html" then "XHTML"
    else if h "<html" then "HTML"
    else if h "<?xml" then "XML"
    else if h("jQuery") or h "document.get" then "JavaScript"
    else if h "def __init__(self" then "Python"
    else if h "\\documentclass" then "TeX"
    else if h("java.") or h "public class" then "Java"
    else if s("SELE") or s("UPDATE") or s "DELE" then "SQL"
    else if /[-\+\.,\[\]\>\<]{9}/.test p then "Brainfuck"
    else if h "NSString" then "Objective-C"
    else if h "do |" then "Ruby"
    else if h("prototype") or h "$(" then "JavaScript"
    else if h "(defun" then "Common Lisp"
    else if /::\s*[a-z]+\s*->/i.test p then "Haskell"
    else if h "using System" then "C#"
    else if h "#include"
        if h("iostream") or h "using namespace" then "C++"
        else "C"
    else "???"

program = ""
process.stdin.on 'data', (chunk) -> program += chunk
process.stdin.on 'end', -> console.log t program

Utilizzo sul nodo: coffee timwolla.coffee < Example.java

Demo (Demo online su JSFiddle ):

[timwolla@~/workspace/js]coffee puzzle.coffee < ../c/nginx/src/core/nginx.c 
C
[timwolla@~/workspace/js]coffee puzzle.coffee < ../ruby/github-services/lib/service.rb
Ruby
[timwolla@~/workspace/js]coffee puzzle.coffee < ../python/seafile/python/seaserv/api.py
Python

Sul mio computer questo non produce nulla, nemmeno su input che ovviamente dovrebbero funzionare. Certo, potrei fare qualcosa di sbagliato in quanto non ho mai usato Coffeescript prima.
Marin

@marinus Notare che quando si inserisce manualmente il codice è necessario inviare un EOF (STRG + D) per attivare l'esecuzione. Generalmente: il rilevatore dovrebbe almeno sputare tre punti interrogativi.
TimWolla,

No, niente. Devo passare coffeequalche argomento? Avevo appena provato a reindirizzare i file in esso, ma solo eseguirlo e andare ^Dnon fa nulla.
Marin

@marinus Prova: npm install coffee-script && node_modules/.bin/coffee timwolla.coffee < timwolla.coffeein una cartella temporanea, questo dovrebbe essere espulso APL. (supponendo che sia installata una versione recente di node e npm)
TimWolla,

5
Inizierò a utilizzare omega minuscole in più nei miei programmi non APL.
John Dvorak,

4

Questa risposta è una prova del concetto, che probabilmente non riceverà altro lavoro da me stesso.

Non è disponibile in diversi modi:

  • L'output non è esattamente come richiesto dalla domanda, ma abbastanza vicino e potrebbe essere facilmente modificato per produrre l'output esatto richiesto.
  • Esistono diversi modi per far funzionare meglio il codice e / o modi migliori per rappresentare le strutture di dati.
  • e altro ancora

L'idea è quella di impostare un elenco di parole chiave / caratteri / frasi in grado di identificare una lingua specifica e assegnare un punteggio a quella parola chiave per ciascuna lingua. Quindi controlla i file di origine per queste parole chiave e calcola i punteggi per ogni lingua per cui trovi le parole chiave. Alla fine la lingua con il punteggio più alto è il probabile vincitore. Ciò si rivolge anche ai programmi poliglotta poiché entrambe (o tutte) le lingue pertinenti avranno un punteggio elevato.

L'unica cosa da aggiungere più lingue è identificare le loro "firme" e aggiungerle alla mappatura.

Puoi anche assegnare punteggi diversi a parole chiave diverse per lingua. Ad esempio, se ritieni che volatilesia usato più in Java che in C, imposta il punteggio per la volatileparola chiave su 2 per Java e 1 per C.

public class SourceTest {

  public static void main(String[] args) {
    if (args.length < 1) {
      System.out.println("No file provided.");
      System.exit(0);
    }
    SourceTest sourceTest = new SourceTest();
    for (String fileName : args) {
      try {
        sourceTest.checkFile(fileName);
      } catch (FileNotFoundException e) {
        System.out.println(fileName + " : not found.");
      } catch (IOException e) {
        System.out.println(fileName + " : could not read");
      }
    }
    System.exit(0);
  }

  private Map<String, LanguagePoints> keyWordPoints;
  private Map<LANGUAGES, Integer> scores;

  private enum LANGUAGES {
    C, HTML, JAVA;
  }

  public SourceTest() {
    init();
  }

  public void checkFile(String fileName) throws FileNotFoundException, IOException {
    String fileContent = getFileContent(fileName);
    testFile(fileContent);
    printResults(fileName);
  }

  private void printResults(String fileName) {
    System.out.println(fileName);
    for (LANGUAGES lang : scores.keySet()) {
      System.out.println("\t" + lang + "\t" + scores.get(lang));
    }
  }

  private void testFile(String fileContent) {
    for (String key : keyWordPoints.keySet()) {
      if (fileContent.indexOf(key) != -1) {
        for (LANGUAGES lang : keyWordPoints.get(key).keySet()) {
          scores.put(lang, scores.get(lang) == null ? new Integer(1) : scores.get(lang) + 1);
        }
      }
    }
  }

  private String getFileContent(String fileName) throws FileNotFoundException, IOException {
    File file = new File(fileName);
    FileReader fr = new FileReader(file);// Using 1.6 so no Files
    BufferedReader br = new BufferedReader(fr);
    StringBuilder fileContent = new StringBuilder();
    String line = br.readLine();
    while (line != null) {
      fileContent.append(line);
      line = br.readLine();
    }
    return fileContent.toString();
  }

  private void init() {
    scores = new HashMap<LANGUAGES, Integer>();

    keyWordPoints = new HashMap<String, LanguagePoints>();
    keyWordPoints.put("public class", new LanguagePoints().add(LANGUAGES.JAVA, 1));
    keyWordPoints.put("public static void main", new LanguagePoints().add(LANGUAGES.JAVA, 1));
    keyWordPoints.put("<html", new LanguagePoints().add(LANGUAGES.HTML, 1));
    keyWordPoints.put("<body", new LanguagePoints().add(LANGUAGES.HTML, 1));
    keyWordPoints.put("cout", new LanguagePoints().add(LANGUAGES.C, 1));
    keyWordPoints.put("#include", new LanguagePoints().add(LANGUAGES.C, 1));
    keyWordPoints.put("volatile", new LanguagePoints().add(LANGUAGES.JAVA, 1).add(LANGUAGES.C, 1));
  }

  private class LanguagePoints extends HashMap<LANGUAGES, Integer> {
    public LanguagePoints add(LANGUAGES l, Integer i) {
      this.put(l, i);
      return this;
    }
  }
}

4

Solo alcune generalizzazioni generali.

Penso che sia abbastanza preciso.

Questo è Ruby a proposito. Accetta input (multilinea) da stdin.

puts case $<.read
when /\)\)\)\)\)/
  "Lisp"
when /}\s+}\s+}\s+}/
  "Java"
when /<>/
  "Perl"
when /|\w+|/
  "Ruby"
when /\w+ :- \w+ \./
  "Prolog"
when /^[+-<>\[\],.]+$/
  "brainfuck"
when /\[\[.*\]\]/
  "Bash"
when /~]\.{,/
  "golfscript"
end

Penso che #include sia un predittore migliore per c. Che dire di #! / Bin / (ba)? Sh per gli script bash / shell?
Trauma digitale,

@DigitalTrauma Sì, penso che tu abbia ragione su #include. Per motivi artistici non ho intenzione di catturare l'hash-bang in cui il nome della lingua è esplicitamente spiegato.
daniero,

#include è un commento nei inifile ephp
Ismael Miguel,

1
+1 per avere il prologo, ma non C :)
SztupY,

1
Vorrei aggiungere \$\w+dopo quello perl per rilevare PHP. Inoltre (\w+)::~\1è di solito un distruttore C ++
SztupY,

2

Javascript - 6 lingue - alta precisione

Lingue attuali: Java, C, HTML, PHP, CSS, Javascript

Lavoro sul principio che ogni volta che un input soddisfa un criterio, viene assegnato un punteggio e sulla base di tale risultato vengono forniti i risultati.

Caratteristiche:

  • Nessuna funzione integrata che determina il tipo di lingua utilizzata.
  • Non dichiara subito che il testo di input è la xlingua nel vedere una parola chiave.
  • Suggerisce anche altre lingue probabili.

Se ritieni che qualcuno dei tuoi input dei programmi (che ho fatto fino ad ora) non venga rilevato o ottenga risultati non validi, ti preghiamo di segnalarli e sarei felice di risolverli.

Esempio di input 1:

class A{public static void main(String[]a){System.out.println("<?php");}}

Uscita campione 1:

My program thinks you have :
Java with a chance of 100%
Php with a chance of 25%
----------------

Spiegazione:

Questo avrebbe dovuto fallire il programma e avrei stampato PHP, ma poiché il mio programma funziona sulla base di punteggi, nulla fallisce e identifica facilmente Java in primo luogo, seguito da altri possibili risultati.

Esempio di input 2:

class A{public static void main(String[]a){System.out.println("HelloWorld!");}}

Uscita campione 2:

Java
----------------

Esempio di input 3:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

Uscita campione 3:

Language not catched! Sorry.
----------------

Il codice:

// Helper functions

String.prototype.m = function(condition){
  return this.match(condition);
};

String.prototype.capitalize = function(){
  return this[0].toUpperCase() + this.substr(1);
};

function getFuncName(func){
  var temp =  func.toString();
  temp = temp.substr( "function ".length);
  temp = temp.substr( 0, temp.indexOf("("));
  return temp.capitalize();
}

// Get input
var lang_input = prompt("Enter programming language");

// Max score of 4 per lang

function java(input){
  var score = 0;
  score += input.m(/class[\s\n]+[\w$]+[\s\n]*\{/) ? 1 : 0;
  score += input.m(/public[\s\n]+static[\s\n]+void[\s\n]+main[\s\n]*/) ? 1 : 0;
  score += input.m(/\}[\s\n]*\}[\s\n]*$/) ? 1 : 0;
  score += input.m(/System[\s\n]*[.][\s\n]*out/) ? 1 : 0;
  return score;
}

function c(input){
  var score = 0;
  // if java has passsed
  if(checks[0][1] >= 3)return 0;

  score += input.m(/^#include\s+<[\w.]+>\s*\n/) ? 1 : 0;
  score += input.m(/main[\s\n]*\([\s\n]*(void)?[\s\n]*\)[\s\n]*\{/) ? 1 : 0;
  score += input.m(/printf[\s\n]+\(/) || input.m(/%d/) ? 1 : 0;
  score += input.m(/#include\s+<[\w.]+>\s*\n/) || input.m(/(%c|%f|%s)/) ? 1 : 0;
  return score;
}

function PHP(input){
  var score = 0;
  score += input.m(/<\?php/) ? 1 : 0;
  score += input.m(/\?>/) ? 1 : 0;
  score += input.m(/echo/) ? 1 : 0;
  score += input.m(/$[\w]+\s*=\s*/) ? 1 : 0;
  return score;
}

function HTML(input){
  var score = 0;
  // if php has passed
  if(checks[2][1] >= 2) return 0;

  score += input.m(/<!DOCTYPE ["' \w:\/\/]*>/) ? 1 : 0;
  score += input.m(/<html>/) && input.m(/<\/html>/) ? 1 : 0;
  score += input.m(/<body>/) && input.m(/<\/body/) ? 1 :  0;
  score += input.m(/<head>/) && input.m(/<\/head>/) ? 1 : 0;
  return score;
}

function javascript(input){
  var score = 0;
  score += input.m(/console[\s\n]*[.][\s\n]*log[\s\n*]\(/) ? 1 : 0;
  score += input.m(/[\s\n]*var[\s\n]+/) ? 1 : 0;
  score += input.m(/[\s\n]*function[\s\n]+[\w]+[\s\n]+\(/) ? 1 : 0;
  score += input.m(/document[\s\n]*[.]/) || 
           ( input.m(/\/\*/) && input.m(/\*\//) ) ||
           ( input.m(/\/\/.*\n/) )? 1 : 0;
  return score;
}

function CSS(input){
  var score = 0;
  score += input.m(/[a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ? 1 : 0;
  // since color is more common, I give it a separate place
  score += input.m(/color/) ? 1 : 0;          
  score += input.m(/height/) || input.m(/width/) ? 1 : 0;
  score += input.m(/#[a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ||
           input.m(/[.][a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ||
           ( input.m(/\/\*/) && input.m(/\*\//) ) ? 1 : 0;
  return score;
}

// [Langs to check, scores]
var checks = [[java, 0], [c, 0], [PHP, 0], [HTML, 0], [javascript, 0], [CSS, 0]];
//Their scores

// Assign scores
for(var i = 0; i < checks.length; i++){
  var func = checks[i][0];
  checks[i][1] = func(lang_input);
}

// Sort the scores
checks.sort(function(a,b){ return b[1] - a[1]; });

var all_zero = true;

function check_all_zero(index){
  if(checks[index][1] > 0){ all_zero = false; return 0; } // someone is above zero

  // check next index only if it defined, else return zero
  if(checks[index + 1])
    check_all_zero(index + 1);
}

check_all_zero(0);

if(all_zero){
  console.log("Language not catched! Sorry.");
}else {
  var new_arr = [];                   // temp

  checks.map(function(value, index){
    if(value[1] > 0){
      var temp = [getFuncName(value[0]), value[1]];
      new_arr.push(temp);
    }
  });

  checks = new_arr.slice(0);          // array copy, because of mutation

  if(checks.length === 1){
    console.log(checks[0][0]);
  }else{
    console.log("My program thinks you have :");
    checks.map(function(value){
      var prob = (value[1]/4 * 100);
      console.log(value[0] + " with a chance of " + prob + "%");
    });
  }

} // Main else block finish

console.log("----------------");
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.