Wykryj, jakim językiem programowania jest fragment kodu

23

Wyzwanie polega na przyjęciu kodu źródłowego jako danych wejściowych i wyjściowych, w jakim języku programowania jest napisany.

Na przykład możesz mieć dane wejściowe

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

I wyjście

Java

Twoimi dwoma głównymi celami są różnorodność (ile języków programowania można wykryć) i dokładność (jak dobry jesteś w wykrywaniu tych języków).

W przypadku poliglotów (programów ważnych w więcej niż jednym języku) możesz zdecydować, co robić. Możesz po prostu wypisać język, który według twojego programu jest bardziej prawdopodobny, lub możesz wypisać błąd, lub możesz wypisać szereg możliwych wyborów (co prawdopodobnie dostanie więcej głosów pozytywnych niż tylko błąd!).

Jest to , ponieważ bardzo trudno byłoby określić inne obiektywne kryterium wygranej. Głosujący, głosujcie, ile języków może wykryć i jak dokładny.

Klamka
źródło
Jest to niemożliwe, ponieważ print("")można go używać w wielu językach.
Ismael Miguel
1
Z twoją edycją wydaje się teraz bardziej możliwa.
Ismael Miguel
4
Co z językami, które są ważne dla KAŻDEGO wprowadzania? Jak spacja. To zdanie jest poprawnym programem do białych znaków. Ta cała strona jest poprawnym programem do białych znaków.
Ismael Miguel
1
Czy wejście jest gwarantowane jako prawidłowy program? Jak niektóre dane wejściowe mogą być class A{public static void main(String[]a){System.println.out("Hello, World!");}}nieprawidłowe.
Gaurang Tandon
1
Czy w podobny sposób zawsze HTML zaczyna się od, <!DOCTYPE html>po którym następuje <html>, <body>i inne tagi (jak meta) w odpowiedniej kolejności?
Gaurang Tandon

Odpowiedzi:

18

234 formaty tekstowe - Unix Shell

(nie wszystkie języki - muszę je dokładnie policzyć)

file $1

Waham się, by opublikować tę nieco sprytną odpowiedź $$, ale nie widzę nic w regułach zakazujących jej, a filenarzędzie powłoki naprawdę dobrze sobie z tym radzi. na przykład:

$ 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
$ 

Ponadto możesz użyć -kopcji „kontynuuj” podczas testowania poliglota:

 -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.)

Ta -lopcja daje również wyobrażenie o tym, jak dobry jest algorytm dla różnych języków:

$ plik -l | muszla grep
nieznany, 0: Ostrzeżenie: używanie zwykłego pliku magii `/ etc / magic '
Siła = 280: tekst archiwum powłoki [application / octet-stream]
Siła = 250: tekst wykonywalny skryptu powłoki Tenex C [tekst / x-shellscript]
Siła = 250: Plik wykonywalny skryptu powłoki Bourne-Again tekst wykonywalny [text / x-shellscript]
Siła = 240: Plik wykonywalny skryptu zsh Paula Falstada [text / x-shellscript]
Siła = 240: tekst wykonywalny skryptu popiołu Neila Browna [tekst / x-shellscript]
Strength = 230: Plik wykonywalny skryptu ae Neila Browna [tekst / x-shellscript]
Siła = 210: Skrypt powłoki Tenex C tekst wykonywalny [text / x-shellscript]
Siła = 210: Skrypt powłoki Bourne-Again tekst wykonywalny [text / x-shellscript]
Strength = 190: Plik wykonywalny skryptu powłoki Tenex C [tekst / x-shellscript]
Strength = 190: Skrypt powłoki Bourne-Again tekst wykonywalny [tekst / x-shellscript]
Strength = 180: Plik wykonywalny skryptu Zsh Paula Falstada [text / x-shellscript]
Siła = 150: tekst skryptu powłoki Tenex C wykonywalny [tekst / x-shellscript]
Strength = 150: Skrypt powłoki Bourne-Again tekst wykonywalny [text / x-shellscript]
Strength = 140: C skrypt wykonywalny skryptu powłoki [text / x-shellscript]
Strength = 140: Skrypt powłoki Korn wykonywalny tekst [text / x-shellscript]
Strength = 140: Skrypt Zsh Paula Falstad'a wykonywalny tekst [text / x-shellscript]
Siła = 130: tekst wykonywalny skryptu powłoki POSIX [tekst / x-shellscript]
Siła = 130: Wykonalny tekst skryptu powłoki 9 Plan RC []
$ 

To jest file-5.09(w Ubuntu 12.04)

Cyfrowa trauma
źródło
To naprawdę działa całkiem nieźle na 16-językowym poliglocie
gist.github.com/riking/9088817
Równie dobrze można wyciąć w środku człowieka i uniknąć powłokę całkowicie: ln -s /usr/bin/file /usr/local/bin/myspecialtool. Jeśli Twoja odpowiedź się liczy, to czy to się nie liczy równie dobrze? (Nie martw się, nie mówię poważnie.)
hvd
2
Wygląda jak standardowa luka, tzn. Delegowanie rozwiązania do istniejącego programu.
Vi.
10

Bash - około 50 35 bajtów na język kompilowalny

Sztuką jest po prostu kompilacja, więc nie musisz się martwić łączeniem błędów z brakujących bibliotek, a bardziej wybaczanie, jeśli masz tylko fragmenty kodu.

Dzięki Shahbaz za krótsze formy!

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)

itp...


źródło
Ponieważ podajesz liczbę bajtów na język kompilacji, możesz zainteresować się liniami takimi jak:gcc -c $1 && (echo C; exit 0)
Shahbaz,
Dziękuję, nie jestem zbyt dobry w wyciskaniu kodu!
Pewnie. &&I ||bash są bardzo przydatne i pomagają Cleanup kod dużo. W żadnym wypadku nie są używane do zaciemniania, więc dobrze byłoby się ich nauczyć.
Shahbaz
2
Możesz także przejść, -fsyntax-onlyaby sprawdzić tylko składnię i pominąć właściwą kompilację.
peppe
7

18 języków programowania, 1002 bajtów, dokładność: sprawdź sam :)

(tak, wiem, że to nie jest golf golfowy, ale dla zabawy)

Program wyszukuje kultowe fragmenty kodu, kontrole są uporządkowane w taki sposób, aby najbardziej przejrzyste kontrole były na górze, a języki programowania osadzone w innych językach programowania były poniżej (np. HTML w PHP).

To oczywiście nie działa w przypadku programów takich jak 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

Zastosowanie w węźle: coffee timwolla.coffee < Example.java

Demo ( wersja demonstracyjna online na 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
TimWolla
źródło
Na moim komputerze nic nie wyświetla, nawet na wejściu, które oczywiście powinno działać. To prawda, że ​​robię coś złego, ponieważ nigdy wcześniej nie korzystałem z Coffeescript.
marinus
@marinus Pamiętaj, że przy ręcznym wprowadzaniu kodu musisz wysłać EOF (STRG + D), aby uruchomić wykonanie. Ogólnie: Detektor powinien wypluć co najmniej trzy znaki zapytania.
TimWolla,
Nie, nic. Czy muszę przekazać coffeejakieś argumenty? Właśnie próbowałem przekierować do niego pliki, ale samo uruchomienie i przejście ^Dnic nie robi.
marinus
@marinus Spróbuj: npm install coffee-script && node_modules/.bin/coffee timwolla.coffee < timwolla.coffeew folderze tymczasowym powinien to wypluć APL. (zakładając, że masz zainstalowaną najnowszą wersję węzła i npm)
TimWolla
5
Zacznę używać więcej małych liter omega w moich programach nie-APL.
John Dvorak
4

Ta odpowiedź jest dowodem koncepcji, że prawdopodobnie nie otrzymam ode mnie żadnej pracy.

Nie działa na kilka sposobów:

  • Wynik nie jest dokładnie taki, jak wymaga tego pytanie, ale jest wystarczająco blisko i można go łatwo zmodyfikować, aby uzyskać dokładnie wymagany wynik.
  • Istnieje kilka sposobów poprawienia wydajności kodu i / lub lepszych sposobów reprezentacji struktur danych.
  • i więcej

Chodzi o to, aby ustawić listę słów kluczowych / znaków / fraz, które mogą zidentyfikować konkretny język i przypisać wynik do tego słowa kluczowego dla każdego języka. Następnie sprawdź pliki źródłowe tych słów kluczowych i zsumuj wyniki dla każdego języka, w którym znajdują się słowa kluczowe. Ostatecznie język z najwyższym wynikiem jest prawdopodobnym zwycięzcą. Dotyczy to również programów poliglotycznych, ponieważ oba (lub wszystkie) odpowiednie języki będą wysoko oceniane.

Jedyną rzeczą, aby dodać więcej języków, jest zidentyfikowanie ich „podpisów” i dodanie ich do mapowania.

Możesz także przypisać różne wyniki do różnych słów kluczowych w każdym języku. Na przykład, jeśli uważasz, że volatilejest używany częściej w Javie niż w C, ustaw wynik dla volatilesłowa kluczowego na 2 dla Java i 1 dla 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;
    }
  }
}
ufis
źródło
4

Tylko kilka ogólnych uogólnień.

Myślę, że to dość dokładne.

To jest Ruby btw. Pobiera (wieloliniowy) wkład ze standardowego wejścia.

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
daniero
źródło
Myślę, że #include jest lepszym predyktorem dla c. Co z #! / Bin / (ba)? Sh dla skryptów bash / shell?
Cyfrowa trauma
@DigitalTrauma Tak, myślę, że masz rację co do #include. Ze względów artystycznych nie zamierzam po prostu łapać haszyszu, w którym nazwa języka jest wyraźnie zapisana.
daniero
#include to komentarz w iniplikach iphp
Ismael Miguel
1
+1 za prolog, ale bez C :)
SztupY
1
Dodałbym \$\w+po perlu, aby wykryć PHP. (\w+)::~\1Zazwyczaj jest także niszczycielem C ++
SztupY
2

JavaScript - 6 języków - wysoka dokładność

Aktualne języki: Java, C, HTML, PHP, CSS, JavaScript

Pracuję na zasadzie, że ilekroć dane wejściowe spełniają kryteria, przyznawane są punkty i na podstawie tych wyników są podawane wyniki.

Cechy:

  • Brak wbudowanych funkcji określających używany typ języka.
  • Nie od razu deklaruje, że tekst wejściowy jest xjęzykiem po zobaczeniu słowa kluczowego.
  • Sugeruje także inne prawdopodobne języki.

Jeśli uważasz, że którekolwiek z twoich danych wejściowych programów (które zrobiłem do tej pory) nie zostały złapane lub uzyskały nieprawidłowe wyniki, zgłoś to, a chętnie je naprawię.

Przykładowe wejście 1:

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

Przykładowy wynik 1:

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

Wyjaśnienie:

To powinno zawieść program i wydrukowałbym PHP, ale ponieważ mój program działa na podstawie wyników, nic nie zawodzi i przede wszystkim łatwo identyfikuje Javę, a następnie inne możliwe wyniki.

Przykładowe wejście 2:

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

Przykładowy wynik 2:

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

Przykładowe wejście 3:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

Przykładowy wynik 3:

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

Kod:

// 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("----------------");
Gaurang Tandon
źródło