言語のバージョンを決定する


51

あなたの挑戦は、あなたの言語の異なるバージョンで動作する多言語を書くことです。実行すると、常に言語バージョンが出力されます。

ルール

  • プログラムは、少なくとも2つのバージョンの言語で動作するはずです。
  • プログラムの出力はバージョン番号のみである必要があります。無関係なデータはありません。
  • プログラムは、好きな方法を使用してバージョン番号を決定できます。ただし、出力はルール2に従う必要があります。ただし、バージョン番号を決定する場合、出力は番号のみでなければなりません。
  • プログラムは、言語のメジャーバージョンを出力するだけで済みます。たとえば、FooBar 12.3.456789-betaでは、プログラムは12を出力するだけで済みます。
  • 言語でバージョン番号の前後に単語または記号を配置する場合、それらを出力する必要はなく、番号のみを出力します。たとえば、C89では、プログラムはprintのみを必要89とし、C ++ 0xでは、プログラムはprintのみを必要とします0
  • フルネームまたはマイナーバージョン番号、たとえばC99ではなくC89を印刷する場合、名前のみを印刷する必要があります。C89 build 32は有効ですが、無効ですerror in C89 build 32: foo bar
  • プログラムは、言語バージョンを決定するために組み込み、マクロ、またはカスタムコンパイラフラグを使用しない場合があります。

得点

スコアは、コードの長さをそれが機能するバージョンの数で割ったものになります。最低スコアが勝ち、幸運を祈ります!


4
言語バージョン番号とは何ですか?誰がそれを決めますか?
小麦ウィザード

9
バージョン数の逆線形は、バージョン数が多い場合の回答を歓迎しないと思います。
user202729

6
@ user202729同意します。汎用性のある整数プリンターはそれをうまくやった(number of languages)^3 / (byte count)
メゴ

6
言語のバージョンは何ですか?ここでは、言語をインタープリター / コンパイラーとして定義しません か?特定のC89コードで動作がC89仕様に違反する実行可能ファイルを生成するバグがあるgccのバージョンがあり、それは次のバージョンのgccで修正されました。このバグ動作に基づいてどのgccバージョンが使用されているかを示すコードの一部を作成する場合、これは有効なソリューションと見なすべきですか?異なるバージョンのコンパイラを対象としていますが、異なるバージョンの言語は対象外です
tsh

6
わかりません。最初に、「プログラムの出力はバージョン番号のみであるべきです」と言います。次に、「フルネームまたはマイナーバージョン番号、たとえばC99ではなくC89を印刷することを選択した場合、名前のみを印刷する必要があります」と言います。最初のルールは実際には要件ではありませんか?
パイプ

回答:


16

真剣かつ実際に、3バイト、スコア1.5

'1u

オンラインで試す:実際真剣に

説明:

'1u
'1   both versions: push "1"
  u  Actually: increment character to "2"; Seriously: NOP
     (both versions: implicit print)

uそしてD文字列の機能のみ(真剣V2である)実際に加えた有します。


3
ActuallyのREADME.mdには、ActuallyがSeriouslyの精神的な後継者であると書かれています。私には単なるバージョン変更のように聞こえません。
アダム

7
@Adámリポジトリ内のブランチを見ると、真剣にv1ブランチに常駐しています。真剣に廃止される前は、実際にv2ブランチに常駐していました。さらに、実際には(そことPyPIの両方で)を使用しながら1.xリリースでは真剣にバージョン番号を使用していました。2.x
メゴ

115

Python 3.0およびPython 2、スコア6

(12バイト、2バージョン)

print(3/2*2)

オンラインで試す:

Python 3+は、floor divisionを使用するPython 2とは異なり、デフォルトでfloat divisionを使用するという事実に依存しています。


@MaltySen Your program should work in at least two versions of your language.少なくとも2つのバージョン2.7および3.0で動作します。私が選んだto print the full name or minor version numbers
fireflame241

ああ、なるほど。
マルティセン

4
ああ、神様!貧しいpython開発者
レジスポルタレス

4
@RegisPortalez from __future__ import division、問題が解決:)
ルカシュRogalski

62

Java、189バイト、10バージョン、スコア= 18.9

サポートされるバージョン:1.01.11.21.31.41.51.61.71.8および9

(以前のスコアについては、履歴を確認してください!)

Object v(){int i=0;try{for(String[]s={"Locale","Map","Timer","Currency","UUID","Deque","Objects","Base64","zip.CRC32C"};;i++)Class.forName("java.util."+s[i]);}finally{return i<9?"1."+i:i;}}

Java 8で
実行Java 9以降で実行

非ゴルフ

Object v(){
  int v=0;
  try {
    for(
      String[] s={
        "Locale",          // 1.1
        "Map",             // 1.2
        "Timer",           // 1.3
        "Currency",        // 1.4
        "UUID",            // 1.5
        "Deque",           // 1.6
        "Objects",         // 1.7
        "Base64",          // 1.8
        "zip.CRC32C"       // 9
      };;v++)
      Class.forName("java.util."+s[v]);
  } finally {
    // Swallowing ClassNotFoundException when the version is not the last one
    // Swallowing ArrayIndexOutOfBoundsException that occurs after reaching the last version.
    return v < 9 ? "1." + v : v; // Return either an int or a String
  }
}

コード部分return v<9?"1."+v:v;(以前return(v<9?"1.":"")+v;)は、Java 1.0とJava 1.3の間に含まれるすべてのバージョンに対してチェックする必要があることに注意してください。この構文を実際にテストするための自由なJava 1.3以前のインストールはありません。

前書き

Javaのバージョン管理には特別な歴史があります。すべてのバージョンには、歴史的に1.x含まれてい1.0ます。しかし... Java 9以降およびJEP223から、バージョンスキーマはからに変更され1.xましたx。これは、内部的に知られているバージョンです。したがって、次の表があります(JavadocおよびWikipediaと一緒に置きます)。

 java.version | Rel. name | Product name
   property   |           |
--------------+-----------+-----------------
          1.0 | JDK 1.0   | Java 1
          1.1 | JDK 1.1   |
          1.2 | J2SE 1.2  | Java 2
          1.3 | J2SE 1.3  |
          1.4 | J2SE 1.4  |
          1.5 | J2SE 5.0  | Java 5
          1.6 | Java SE 6 | Java 6
          1.7 | Java SE 7 | Java 7
          1.8 | Java SE 8 | Java 8
          9   | Java SE 9 | Java 9

このチャレンジエントリは、上記の表のバージョン列と一致します"java.version"。これは、システムプロパティに含まれています。

説明

Javaのコードは廃止されますが、削除されることはないため、目標は、クラスの存在を開始するバージョンを確認することです。JDKは(ほとんどの場合)ソースの前方互換性があるためコードはすべてのバージョンと互換性があるようにJava 1.0で具体的に記述されています。

実装は、各バージョンが導入した最短のクラス名を見つけようとします。ただし、バイト数を増やすには、共通のサブパッケージを選択する必要があります。これまでのところ、最も効率的なパッケージはjava.util、Javaのすべてのバージョンに散らばっている本当に短い名前のクラスがいくつか含まれているためです。

現在、実際のバージョン番号を見つけるために、クラス名は導入バージョンによってソートされています。次に、各クラスを順番にインスタンス化し、配列のインデックスを増やしてみます。クラスが存在する場合は次へスキップし、存在しない場合はtry-blockで例外をキャッチします。終了すると、存在を確認する必要のあるクラスがもうないため、別の例外がスローされます。

いずれの場合でも、スレッドはtry-blockを例外のままにします。その例外はキャッチされませんが、単にfinally-blockのおかげで保留になります。これは"1."+vv以前に使用されたインデックスがある場所に実際に値を返すことにより、保留例外をオーバーライドします。また、このインデックスをJavaのマイナーバージョン番号と一致させました。

ゴルフの重要な部分は、java.util各バージョンのパッケージ(または子パッケージ)で最短の新しいクラス名を見つけることでした。以下は、そのコストを計算するために使用した表です。

Base cost: `java.util.` (10 chars)

 Version | Class name (cost in chars)     | Reduced name (cost in chars)
---------+--------------------------------+---------------------------
 9       | java.util.zip.CRC32C (20)      | zip.CRC32C (10)
 1.8     | java.util.Base64 (16)          | Base64 (6)
 1.7     | java.util.Objects (17)         | Objects (7)
 1.6     | java.util.Deque (15)           | Deque (5)
 1.5     | java.util.UUID (14)            | UUID (4)
 1.4     | java.util.Currency (18)        | Currency (8)
 1.3     | java.util.Timer (15)           | Timer (5)
 1.2     | java.util.Map (13)             | Map (3)
 1.1     | java.util.Locale (16)          | Locale (6)
 1.0     | <default>                      | <default>
---------+--------------------------------+---------------------------
Subtotal |                      144 chars |                  54 chars
    Base |                                |                  10 chars
   Total |                      144 chars |                  64 chars

クレジット

  • Kevin Cruijssenのおかげで30バイト節約されました(彼のコメントを読む前にやっていましたが、約束します!)。
  • ニールのおかげでさらに26バイト節約されました(いいえ、私はそれをすることを考えていませんでした)
  • 12はNevayと素敵な外のおかげバイト-box -tryキャッチ思考を!
  • Neilによる11バイトの追加と、優れたポータブルfinallyトリック。
  • より2は、置換することによって、ケビンCruijssenのおかげでバイトreturn(i<9?"1.":"")+i;してreturn i<9?"1."+i:i;(このニーズが1.0に対して検証、または全く構文の変更以来、1.3、最大で1.4の前に起こったことにします)

ビルトイン

組み込みが許可された場合:

String v(){return System.getProperty("java.version");}

13バージョン(1.0から12)で54バイトなので、スコアは4.1538になります。


1
:@KevinCruijssen私は、私は、このページによるビット助けられた... 1.で短い名前1とのjavadocとRANクラスを開いた。しかしdocs.oracle.com/javase/8/docs/technotes/guides/lang/...を
オリヴィエグレゴワール

1
260バイトまたはそれ以上の場合return"...、すべてのバージョンでスペースなしで可能かどうかわからないtbh。)
ケビンCruijssen

1
235バイト:String v(){return "1."+(e("time.Year")+e("nio.file.Path")+e("io.Console")+e("util.UUID")+e("text.Bidi")+e("util.Timer")+e("sql.Ref")+e("lang.Void"));}int e(String c){try{Class.forName("java."+c);return 1;}catch(Exception e){return 0;}}
ニール

3
216バイト:String v(){int i=0;try{for(String[]s={"lang.Void","sql.Ref","util.Timer","net.URI","util.UUID","net.IDN","nio.file.Path","time.Year","lang.Module"};;i++)Class.forName("java."+s[i]);}catch(Exception e){}return"1."+i;}
Nevay

1
ああ、私は配列を繰り返して例外をキャッチすることについて疑問に思っていましたが、でもっとうまくいくことができますfinally{return"1."+i;}
ニール

22

Python、606バイト/ 15バージョン=スコア40.4

-67バイト(笑)NoOneIsHereに感謝します。

バージョンは0.9.1、2(.0)、2.2、2.2.2、2.5.0、2,5.1、3(.0)、3.1、3.1.3、3.2.1、3.3、3.4、3.5 aaおよび3.6です。 。

try:eval('1&2')
except:print('0.9.1');1/0
if`'\n'`<'\'\\n\'':print(2);1/0
try:from email import _Parser;print(2.2);1/0
except:0
try:eval('"go"in""')
except:print('2.2.2');1/0
try:int('2\x00',10);print(2.5);1/0
except:0
if pow(2,100)<1:print('2.5.1');1/0
if str(round(1,0))>'1':print(3);1/0
if format(complex(-0.0,2.0),'-')<'(-':print(3.1);1/0
if str(1.0/7)<repr(1.0/7):print('3.1.3');1/0
try:eval('u"abc"')
except:print('3.2.1');1/0
try:int(base=10);print(3.3);1/0
except:0
try:import enum
except:print('3.3.3');1/0
try:eval('[*[1]]')
except:print(3.4);1/0
try:eval('f""')
except:print(3.5);1/0
print(3.6)

Sp3000の驚くべき答え感謝します。末尾の改行が必要です。

Whee、それはゴルフが楽しかったです。これは機能するはずです(はい、これらのバージョンをすべてインストールしました)が、誤って何かを中断した可能性があります。誰かがバグを見つけたら、私に知らせてください。



...ああ、当然です。Sp3000がすべてのprint通話で括弧を使用している理由を知りたいと思いました...知らせてくれてありがとう!
完全に人間

2
特定のタイプのエラーを削除することにより、68バイトを節約できます(すべてexceptのsをに置き換えますexcept:)。
-NoOneIsHere

x=<string inside eval>コードを手動で評価する代わりにこれを実行した場合、これはまだ機能しますか?
ブルー

@NoOneIsHere最初は、すべてのためにあなたはできなかったと1/0思っていましたが、それから私は気づきました。ありがとう!
完全に人間

21

C ++ 11/14/17、スコア= 147/3 = 49

C ++ 11とC ++ 14/17を区別するために、デフォルトの変更を使用します constconstexprメンバー関数の(https://stackoverflow.com/questions/23980929/の例の功績による)c14で導入された変更が、c1で書かれたプログラムを中断する可能性があります)。C ++ 14とC ++ 17を区別するために、C ++ 17がトライグラフを無効にしているという事実を使用します。

#include<iostream>
#define c constexpr int v
struct A{c(int){return 0;}c(float)const{return*"??="/10;}};int main(){const A a;std::cout<<11+a.v(0);}

ゴルフをしていない:

struct A {
    constexpr int v(int) { return 0; }
    constexpr int v(float) const {
        // with trigraphs, *"??=" == '#' == 35, v() returns 3
        // without trigraphs, *"??" == '?' == 63, v() returns 6
        return *("??=") / 10;
    }
};

int main() {
    const A a;
    std::cout << 11 + a.v(0);
}

(を使用してDebian gcc 7.1.0でテスト済み-std=c++{11,14,17}。)


1
素晴らしい最初の答え!includeステートメントでincludeとの間のスペースをゴルフすることができます。<#include<iostream>
MD XF

1
うーん...標準ライブラリの違い(この場合は間接的に__cplusplusマクロを使用する)を使用することを禁止するようにルールが修正された場合-C ++ 17とC ++ 14を区別するために、範囲ベースの変更を使用することに傾倒しますセマンティクス用。boost::integer_iteratorセンチネルをイテレータに変換すると「驚くべき」動作になるように、最小限のイテレータ/センチネルクラスを作成することもできます。
ダニエルシェプラー

4
return 0;暗黙的であるmainため、そこに9バイトを保存できます。また、wc -cあなたのソリューションによると、252ではなく251バイトを使用しています(エディタが最後に改行を挿入した可能性があります)。
NWP

1
14 C ++から独立したC ++ 17にトリグラフの欠如を使用することはおそらく短い
Potato44

1
これは機能しますか?return *=>return*
ザカリー

19

EcmaScript 3/5/2015/2016/2017 in Browser、59バイト/ 5バージョン= 11.8ポイント

alert(2017-2*![].map-2010*![].fill-![].includes-!"".padEnd)

NetScape 7 report 3, and Opera 12 report 5

GOTO 0のおかげで1バイト節約


1
忍者!;)
シャギー

Netscape 7はES3のみをサポートしていましたか?うわー、思ったよりも古いです
ニール

1
意味の-!ある+!!場所ではなく、使用して数バイトを節約できます(それに応じて数値定数を変更します)。
GOTO 0

3
たぶんいくつかの説明?:)
デレク朕會功夫

@Derek:説明については、私のソリューション(上記のリンク)を参照してください。
シャギー

18

JavaScript(ES5およびES6)、14バイト/ 2バージョン= 7

alert(5^"0o3")

0oスタイルの8進定数はES6で新しく追加されました。ES5 NaNは、ビット単位のXORの結果に影響しない文字列をキャストします。


13

JavaScriptの(ES 2,3、および5 - 8 9)、 6分の59 = 9.833 7分の75 = 10.714

2バージョンのソリューションよりもわずかに高いスコアを付けたとしても、より多くのバージョンのソリューションを提出することもできます。

alert(9-(/./.dotAll!=0)-!"".padEnd-![].includes-![].keys-2*![].map-![].pop)

オンラインで試す

Array、RegExp、およびStringプロトタイプ内のさまざまなメソッドの存在を確認し、それらを否定してブール値を与え、そのブール値を初期値9から減算し![].mapます。ES4が放棄されたという事実の乗算。

  • 正規表現のdotAllプロパティ(および関連sフラグ)はES2018(v9)で導入されました
  • padEnd文字列方法はで導入されたES2017(V8)。
  • includesアレイ法は、で導入されたES2016(V7)。
  • keysアレイ法は、で導入されたES2015(V6)。
  • mapアレイ法は、で導入されたES5.1(V5)。
  • popアレイ法は、で導入されたES3(V3)。

ES 7またはES 8は有効なバージョン番号ですか?たぶんそれはES 201xと呼ばれるべきですか?
tsh

1
@tsh:はい、彼らはまだバージョン番号を使用しています。彼らは本当の名前に何年も使います
シャギー


9

Befunge:15 11バイト/ 2バージョン= 5.5

@ Pietu1998によって削り取られた4バイト

"89",;5-;,@  

オンラインで試す:
Befunge 93
Befunge 98
Befunge 98専用のセミコロン演算子(「次のセミコロンにスキップ」)を使用してバージョンを区別します。両方とも「9」を印刷します。Befunge 93はセミコロンを無視し、「8」から5を減算し(スタックの一番上の値)、結果の「3」を出力して終了します。一方、Befunge 98はスキップし、「8」を出力して終了します。


"89",;5-;,@11バイト
PurkkaKoodari

@ Pietu1998いいね!それを回答として投稿したい場合は、喜んで
賛成票を投じ

必要に応じて、先に進んで、;部品を見つけました。
-PurkkaKoodari

@ Pietu1998編集中。ありがとうございます!
-karhell

参考までに、私はそれをなんとか7バイトに減らし、別のアプローチを取りました。リンク
ジェームズホルダーネス

7

Pyth 4/5-6バイト/ 2バージョン= 3

  5 ;4

Pyth 5では、行頭の偶数のスペースはインデントに使用するために無視されますが、Pyth 4では1つのスペースのように動作し、5。Pyth 4では、セミコロンはステートメントを終了するだけです。これにより、4を印刷できます。一方、Pyth 5では、スペースとセミコロンが行の残りの部分をコメントにします。


11
Pythにバージョンがあることを誰が知っていましたか?
エリックアウトゴルファー


7

通常、4バイト、スコア4 /∞

B3%0

システムに実行するのに十分なメモリがあるすべてのバージョンで動作します。それは足の不自由だからです。このメタ投稿ごとに有効。

基本的に、B3は左面から上面に1行回転します。F3は、F₁3またはB₁3と同様に機能します。立方体の3×3×3のように1つの行が1 cubeletによる三cubelets、このプット3で1それを3の面の和与え上面への、%0立方体3印刷、上面和ことプリントを3 x3x3を。

Cubically 4x4x4では、行は4x1立方体です。4の1を上面に置き、合計4を生成します。


9
スコアは4 /∞にすべきではありませんか?
nwp

7

x86 16/32/64ビットマシンコード:11バイト、スコア= 3.66

この関数は、現在のモード(デフォルトのオペランドサイズ)をALの整数として返します。署名付きでCから呼び出すuint8_t modedetect(void);

NASMマシンコード+ソースリスト(16ビットモードBITS 16のソースニーモニックをアセンブルするようNASMに指示するため、16ビットモードでの動作を示す)

 1          machine      global modedetect
 2          code         modedetect:
 3 addr     hex          BITS 16

 5 00000000 B040             mov    al, 64
 6 00000002 B90000           mov    cx, 0       ; 3B in 16-bit.  5B in 32/64, consuming 2 more bytes as the immediate
 7 00000005 FEC1             inc    cl          ; always 2 bytes.  The 2B encoding of inc cx would work, too.
 8                       
 9                           ; want: 16-bit cl=1.   32-bit: cl=0
10 00000007 41               inc    cx       ; 64-bit: REX prefix
11 00000008 D2E8             shr    al, cl   ; 64-bit: shr r8b, cl doesn't affect AL at all.  32-bit cl=1.  16-bit cl=2
12 0000000A C3               ret
# end-of-function address is 0xB, length = 0xB = 11

正当化

x86マシンコードには正式なバージョン番号はありませんが、これは最も便利なもの(7バイトしかかからない、以下を参照)を選択するのではなく、特定の番号を生成することで質問の意図を満たしていると思います。

元のx86 CPUであるIntelの8086は、16ビットのマシンコードのみをサポートしていました。80386は32ビットのマシンコードを導入しました(32ビットの保護モードで使用でき、後で64ビットOSの互換モードで使用できます)。AMDは、ロングモードで使用可能な64ビットマシンコードを導入しました。これらは、Python2とPython3が異なる言語バージョンであるという同じ意味でのx86マシン言語のバージョンです。ほとんど互換性がありますが、意図的に変更されています。Python2およびPython3プログラムを実行するのと同じ方法で、32ビットまたは64ビットの実行可能ファイルを64ビットOSカーネルの下で直接実行できます。

使い方:

で始まりal=64ます。1(32ビットモード)または2(16ビットモード)だけ右にシフトします。

  • 16/32対64ビット:1バイトinc/ decエンコーディングは、64ビットのREXプレフィックスです(http://wiki.osdev.org/X86-64_Instruction_Encoding#REX_prefix)。REX.Wは一部の命令にまったく影響を与えません(たとえば、a jmpまたはjcc)が、この場合は16/32/64 を取得するために、ecxでなくincまたはdecにしたかったのですeax。また、が設定REX.Bされ、宛先レジスタが変更されます。しかし幸いなことに、私たちはそれを機能させることができますが、64ビットがシフトする必要がないように設定しますal

    16ビットモードでのみ実行される命令にはを含めることができますがret、その必要性や有用性はわかりませんでした。(そして、あなたがそれをしたい場合には、コードフラグメントとしてインライン化することを不可能にします)。また、可能性がjmp関数内。

  • 16ビットと32/64:イミディエートは32ビットではなく16ビットです。モードを変更すると、命令の長さが変わる可能性があるため、32/64ビットモードでは、個別の命令ではなく、イミディエイトの一部として次の2バイトをデコードします。16ビットモードで32/64とは異なる命令境界からデコードするように、デコードを同期から外すのではなく、ここで2バイトの命令を使用することにより、物事をシンプルにしました。

    関連:オペランドサイズのプレフィックスは、16ビットモードと32/64ビットモードの違いのように、即値の長さを変更します(符号拡張された8ビットの即値でない限り)。これにより、命令長のデコードを並行して行うことが難しくなります。Intel CPUにはLCPデコードストールがあります。


ほとんどの呼び出し規約(x86-32およびx86-64 System V psABIを含む)では、狭い戻り値でレジスターの上位ビットにガーベッジを含めることができます。また、CX / ECX / RCX(および64ビットのR8)を上書きすることもできます。IDKは、16ビットの呼び出し規則では一般的でしたが、これはコードゴルフなので、とにかくカスタム呼び出し規則であると言うことができます。

32ビット逆アセンブリ

08048070 <modedetect>:
 8048070:       b0 40                   mov    al,0x40
 8048072:       b9 00 00 fe c1          mov    ecx,0xc1fe0000   # fe c1 is the inc cl
 8048077:       41                      inc    ecx         # cl=1
 8048078:       d2 e8                   shr    al,cl
 804807a:       c3                      ret    

64ビットの逆アセンブリオンラインで試してみてください!):

0000000000400090 <modedetect>:
  400090:       b0 40                   mov    al,0x40
  400092:       b9 00 00 fe c1          mov    ecx,0xc1fe0000
  400097:       41 d2 e8                shr    r8b,cl      # cl=0, and doesn't affect al anyway!
  40009a:       c3                      ret    

関連:SOでのx86-32 / x86-64ポリグロットマシンコード Q&A

16ビットと32/64のもう1つの違いは、アドレス指定モードのエンコード方法が異なることです。例lea eax, [rax+2]8D 40 02lea ax, [bx+si+0x2]16ビットモードのようにデコードします。これは、特に以来、明らかにコードゴルフのために使用することは困難であるe/rbxe/rsi多くの呼び出し規約では、コール保存されています。

またmov r64, imm64、REX +である10バイトの使用を検討しましたmov r32,imm32。しかし、私はすでに11バイトのソリューションを持っているので、これはせいぜい等しい(10バイト+の場合は1 ret)でしょう。


32および64ビットモードのテストコード。(実際に16ビットモードで実行したことはありませんが、逆アセンブリではデコード方法が示されます。16ビットエミュレーターがセットアップされていません。)

; CPU p6   ;  YASM directive to make the ALIGN padding tidier
global _start
_start:
    call   modedetect
    movzx  ebx, al
    mov    eax, 1
    int    0x80        ; sys_exit(modedetect());

align 16
modedetect:
BITS 16
    mov    al, 64
    mov    cx, 0       ; 3B in 16-bit.  5B in 32/64, consuming 2 more bytes as the immediate
    inc    cl          ; always 2 bytes.  The 2B encoding of inc cx would work, too.

    ; want: 16-bit cl=1.   32-bit: cl=0
    inc    cx       ; 64-bit: REX prefix
    shr    al, cl   ; 64-bit: shr r8b, cl doesn't affect AL at all.  32-bit cl=1.  16-bit cl=2
    ret

このLinuxプログラムはexit-status = modedetect()で終了するため、として実行します./a.out; echo $?。静的バイナリにアセンブルしてリンクします。例えば

$ asm-link -m32 x86-modedetect-polyglot.asm && ./x86-modedetect-polyglot; echo $?
+ yasm -felf32 -Worphan-labels -gdwarf2 x86-modedetect-polyglot.asm
+ ld -melf_i386 -o x86-modedetect-polyglot x86-modedetect-polyglot.o
32
$ asm-link -m64 x86-modedetect-polyglot.asm && ./x86-modedetect-polyglot; echo $?
+ yasm -felf64 -Worphan-labels -gdwarf2 x86-modedetect-polyglot.asm
+ ld -o x86-modedetect-polyglot x86-modedetect-polyglot.o
64

## maybe test 16-bit with BOCHS somehow if you really want to.

バージョン1、2、3に番号を付けることができる場合、7バイト(スコア= 2.33)

さまざまなx86モードの公式バージョン番号はありません。asmの回答を書くのが好きです。モード1、2、3、または0、1、2を呼び出しただけでは、不便な番号を生成するように強制することになるため、質問の意図に反すると思います。しかし、それが許可された場合:

 # 16-bit mode:
42                                  detect123:
43 00000020 B80300                      mov ax,3
44 00000023 FEC8                        dec al
45                                  
46 00000025 48                          dec ax
47 00000026 C3                          ret

32ビットモードでデコードするもの

08048080 <detect123>:
 8048080:       b8 03 00 fe c8          mov    eax,0xc8fe0003
 8048085:       48                      dec    eax
 8048086:       c3                      ret    

および64ビットとして

00000000004000a0 <detect123>:
  4000a0:       b8 03 00 fe c8          mov    eax,0xc8fe0003
  4000a5:       48 c3                   rex.W ret 

これらが異なるバージョンとしてカウントされるかどうかはわかりません。それらは単に異なるシステム構成に相関しているだけではありませんか?
ウリエル

1
@Uriel:16ビットモード、32ビットモード、または64ビットモードでCPUを使用してマシンコードのブロックを実行することは、同じPythonプログラムで実行するpython2vs python3インタープリターに相当するマシンコードです。新しいx86 CPUには常に古いCPUと互換性のあるモードが含まれています(これは、そのような複雑な解読困難なマシンコード形式を使用する唯一の言い訳です!)が、386の32ビット保護モードとx86-64のロングモードは本当にx86マシンコードの新しいバージョン。ロングモードでは一部のオペコードも削除され、無効になりました。
ピーター

5

Brachylog / Brachylog v1、5 / 2 = 2.5

2,1hw

オンラインでお試しください!(ブラキログ)

オンラインでお試しください!(Brachylog v1)

Brachylogの説明:

?2,1hw.
?2      Unify ? (input) with 2 (no input so it succeeds)
  ,1    Append 1 (21)
    h   First element/head (2)
     w. Write to STDOUT and unify with output (not displayed)

Brachylog v1の説明:

?2,1hw.
?2      Unify ? (input) with 2 (no input so it succeeds)
  ,     Break implicit unification/logical AND
   1h   Take first element/head of 1 (1)
     w. Write to STDOUT and unify with output (not displayed)

すばらしいです!補足として、2,1Brachylog v2ではリストを作成するのではなく[2,1](リストを作成します2;1)、番号を作成します21(これにより、回答の意図する方法が変わりません)。
致命的

私はゼリー...であることを混同@Fatalize Oohのおかげ
エリックOutgolfer

@Fatalize BTW 2;1は、Brachylog v1では;論理OR として機能しませんでした。
エリックアウトゴルファー

5

C89 / C99、25バイト、2バージョン、スコア= 12.5

#include <stdio.h>

int main() {
    int v = 11 //**/ 11
            + 88;
    printf("C%d\n", v);
    return 0;
}

// スタイルコメントはC89では認識されません。

ゴルフバージョン:

v(){return 20//**/2
+79;}

オンラインで試す:C89C99


に置き換えint v()てくださいmain()。短くなり、実際には完全なプログラムとしてコンパイルされます。
アンドレア

@Andreaありがとう。私の知る限り、関数またはプログラム全体のいずれかを投稿できます。
nwellnhof

正解です。
アンドレア

5

Perl 5およびPerl 6、23 バイト 19バイト、スコア9.5

print 6-grep '.',''

Perl 5のgrep最初のopは常に正規表現として扱われますが、Perl 6ではそうではありません。


スコアは19/2 = 9.5
ダニエルヴェストル

5

Bash、4つのバージョンすべて、72 71 32バイト⇒スコア= 8

s=$'\ua\xa\n';expr 5 - ${#s} / 2

このコードは$'...'、Bashの各バージョンの文字列の異なる解釈を利用します。
メジャーバージョン番号を出力します-それだけです。

ここでドキュメントが見つかりまし

ゴルフをしていない:

s=$'\ua\xa\n';
expr 5 - ${#s} / 2
# Bash v4 sees three linefeeds => length of 3 => 5 - 3 / 2 = 4
# Bash v3 sees the literal '\ua' + two linefeeds: 5 chars in length
#    => 5 - 5 / 2 = 3
# Bash v2 sees '\ua\xa' + linefeed, 7 chars: 5 - 7 / 2 = 2
# Bash v1 does not even interpret $'..' strings, and sees literally '$\ua\xa\n' of length 9 => 5 - 9 / 2 = 1

この答えは半ば推測です。bash 4と3でのみテストしましたが、他のバージョンでも動作するはずです。

そうであるかどうかを教えてください。入手可能になり次第、他のバージョンで試します。

イェンスのおかげで-1文字。
Digital Trauma(exprアイデア全体)のおかげで-29バイト!


シェルの文法は;;、最後の選択肢では必要ありません。;バイトを削るために使用します。
イェンス

1
私はちょうどbash-2.05a(Cygwin用に今コンパイルされています)でこれを試しましたが、「2」ではなく「3」を誤って報告します:(
Jason Musgrove

1
解釈$'\xN機能は2.01.1で追加されたようです...答えを更新する必要があります。それに取り組んで
-joH1

これを試してもらえますか?s="$'\ua\xa\n'";case ${#s} in 3)echo 4;;5)echo 3;;7)echo 2;;9)echo 1;esac
joH1

1
これのようなものにゴルフできるかもしれませんs=$'\ua\xa\n';expr 5 - ${#s} / 2。これはv3およびv4で機能します。今試してみるために古いバージョンを使っているわけではありません。
デジタル外傷

4

R、バージョン2および3、スコア:10.5ポイント

cat(exists("cite")+2)

このコマンドは2、R 2.xxおよび3R 3.xxに対して返されます。関数citeはRバージョン3.0.0で追加されました。したがって、コマンドexists("cite")FALSER 2.xxおよびTRUE R 3.xxに対して

R、すべてのバージョン(1、2、および3)、スコア:12⅓ポイント

e=exists;cat(e("cite")+e("eapply")+1)

この関数eapplyはR 2.0.0で導入されました。


R.version$major。15文字。それが存在するときから私はしません。
ルイバラダ

@RuiBarradas OPを引用させてください:「プログラムは、言語バージョンを決定するために、組み込み、マクロ、またはカスタムコンパイラフラグを使用できません。
Sven Hohenstein

OK、すみません、私はその部分を見逃しました。コメントを削除する必要がありますか?
ルイバラダ

@RuiBarradas問題ありません。コメントを削除する必要はありません。
スベンホーエンシュタイン

結果の印刷を処理する必要があります。現在、完全なプログラムとして実行すると、何も出力されません。
-JAD

4

Python、196バイト/ 16バージョン=スコア12.25

バージョンは1.5、1.6、2.0、2.1、2.2、2.3、2.4、2.5、2.6、3.0、3.1、3.2、3.3、3.4、3.5、および3.6です。
残念ながら、モジュールが含まれていないため、2.7を省かなければなりませんでした2.6ではなく3.0である(私が知る限り)。

i=15
try:
 for m in'os.atexit.os.os.os.warnings.cgitb.heapq.collections._ast.abc.queue.os.os.os.importlib.argparse.lzma.asyncio.zipapp.secrets.'.split('.'):__import__(m);i=i+1
except:print(i/10.)

さまざまなバージョンのpythonで導入された多数のモジュールをループ処理し、最初のエラーでバージョンを終了して返します。メジャーバージョン間のギャップは、繰り返しインポートすることで埋められosます。Python 1.5のテストは、string.split 1.6まで存在ないことにいます。

功績オリヴィエ・グレゴワールの答えループで新しいクラス/モジュールのためのテストのアイデアについて。

私はついに、Pythonのすべての関連バージョンでテストしました... 1.5ソースコードを編集してコンパイルする必要がありました...


4

Windowsのバッチファイル、35バイト/ 2バージョン=スコア17.5

@if /i Z==z @echo NT&exit
@echo DOS

DOSMS-DOS (duh)およびNTWindows NTで印刷します。(だよ)

さて、説明のために。

WindowsはMS-DOS時代からバッチスクリプトを使用しており、それ以降ほとんど変更されていません。ただし、Windows NTが登場したとき、MicrosoftはバッチスクリプトのデフォルトインタープリターをCOMMAND.COMからcmd.exe(今は拡張機能.cmdを元の代替として許可しています.bat)に変更しました。

それに伴い、彼らはまた /i条件付きで文字列の大文字小文字を無視するためのフラグなどいくつかの変更。つまり、Z==zfalseです/i Z==zが、trueです。

DOSに大文字小文字の区別がないことを活用し、大文字を比較します Z小文字のと小文字z/iフラグを使用すると、Z==zDOSでは(false)条件付きz==z、NTでは(true)条件になります。

今、私は、チャレンジがバージョン番号を印刷することを指定していることに気付きました。しかし、私が知る限り、バッチスクリプトに「バージョン番号」はないため、これが最も近い方法です。


Windows 10、DOSBoxおよびvDosでテスト済み:

ウインドウズ10:

ウインドウズ10

(で実行 cmd /kウィンドウを閉じる前にexit

DOSBox:

DOSBox

vDos:

vDos


Windows 7はWindows よりも短いですNT
-user202729

2
@ user202729私は、しかし再び、7実際には言語バージョンではないと思います。3.1 以降、すべてのWindowsで同じでした。私はそれを呼び出すことは非常に公平であるとは思わなかったので7、それは多分あるべきとき3.1
マテウスAvellar

3

Wolfram言語/ Mathematica 10 / 11、37バイト/ 2バージョン= 18.5

考えてみましょう(Length@DateRange[{1},{1}][[1]]+27)/337バイトであり、2つのバージョンで作業し、私に18.5のスコアを与えます。

In[1]:= $Version

Out[1]= "10.4.1 for Microsoft Windows (64-bit) (April 11, 2016)"

In[2]:= (Length@DateRange[{1}, {1}][[1]] + 27)/3

Out[2]= 10

そして

In[1]:= $Version

Out[1]= "11.1.1 for Microsoft Windows (64-bit) (April 18, 2017)"

In[2]:= (Length@DateRange[{1}, {1}][[1]] + 27)/3

Out[2]= 11

もっと効率的な方法があると確信していますが、DateRangeの出力の不一致が最近気に入らないので、それを使用することにしました。

フォローアップとして、だれかがMathematicaバージョン1〜8 でLength@DateRange[{1}, {1}][[1]]評価することを利用できるかもしれ1ませんが、それを組み込む時間はありませんでした。


2
あなたの答えが原因あなたが使用してプロンプト、つまり最後のルールの要件を満たしていないことをかなりしてください$VersionYour program may not use a builtin, macro, or custom compiler flags to determine the language version.
Amndeep7

7
私は$Versionそれが正しいバージョンで正しい結果を出力することを実証するためにのみ使用しています、$Version私の答えの一部ではありません
...-user6014

すべての良い友達-事は、あなたがのようなものを使用している$VersionNumberが、代わりにそれを呼び出しているということ$Versionです。私の考えでは、あなたのプログラムの中身はLength@DateRange重要なものですが、それは$Versionあなたがその後処理する完全なバージョン情報を提供しなければ動作しません。したがって、ルールに違反します。
Amndeep7

4
@ Amndeep7提出は、最初の段落でインライン化された37バイトのコードです。コードブロックは、出力デモのみです。
-PurkkaKoodari

3
説明:異なるバージョンで異なる形式の時間を使用しています。それは{1} Tr[1^#&@@%~DateRange~%]/3+9(31バイト)、または7+Length@Now(12バイト)までゴルフすることができます
user202729

3

Ruby 1.xおよび2.x、20バイト、スコア10

p [].to_h&&2rescue 1

Ruby 2のクラスでto_h導入されたメソッドに基づいていArrayます。


いい最初の答え。テストするのに便利な1.xはありませんp [].to_h&&2rescue 1が、少し短くなっています。
マナトワーク

@manatwork素晴らしい、3バイトを節約し、魅力のように動作します
フィリップフランク

3

アーラン、180バイト、11バージョン、スコア16.36

20-length([A||A<-[schedulers,c_compiler_used,cpu_topology,snifs,dynamic_trace,port_count,nif_version,end_time,max_heap_size,atom_count],{'EXIT',_}<-[catch erlang:system_info(A)]]).

インデントと改行あり:

20-length([A||A<-
                  [schedulers,
                   c_compiler_used,
                   cpu_topology,
                   snifs,
                   dynamic_trace,
                   port_count,
                   nif_version,
                   end_time,
                   max_heap_size,
                   atom_count],
              {'EXIT',_}<-[catch erlang:system_info(A)]]).

10以降の各メジャーバージョンのマイナーリリースでテスト済み:

  • R10B-9
  • R11B-5
  • R12B-5
  • R13B04
  • R14B04
  • R15B03
  • R16B03
  • 17.5.6.2
  • 18.2.1
  • 19.2
  • 20.0

アイデアは、すべてのメジャーリリースがfunction erlang:system_infoに少なくとも1つの新しい許容可能な引数を追加しているため、リスト内の引数を試し、それらの失敗の数をカウントし、現在のバージョンである20から失敗の数を減算しましょう。


3

ジュリア0.4、0.5、46バイト、スコア22

f(::ASCIIString)=.4
f(::String)=.5
f()=f("")

Juliaは、多くのバージョンで具象および抽象String型の型名を変更しました。

このコードは特に次の利点を活用します。

ジュリア0.4

  • コンクリートは ASCIIString
  • アブストラクトは正式に AbstractString
  • Abstractは、次のエイリアスを廃止しました String
  • コンクリートは抽象よりも最も具体的であるため、ディスパッチに勝ちます

ジュリア0.5

  • コンクリートは公式に String
  • コンクリートの別名は廃止されました ASCIIString、。
  • アブストラクトは AbstractString、(ここでは重要ではありませんが)
  • 具体的な文字列型には2つのメソッドが定義されているため、後者は前者を上書きします。

さまざまな原則に基づいた私のより効果的なソリューションも参照してください


3

Japt(1&2)、8 6/2 = 4 3

'1r\S2

テストv1  |   テストv2


説明

v2より前は、JaptはカスタマイズされたRegEx構文を使用していたため、これを利用できます。

'1

文字列としての数値1。

 r  2

r以下を2。に置き換えます。

\S

Japt 2はこれをRegExと見なし/\S/g、これはに一致し1ます。Japt 1は\エスケープ文字を無視し、単にを参照しますS。これは、スペース文字のJapt定数であり、明らかにに一致しません1


3

Befunge、スコア= 3.5

7バイト、2バージョン

"]"'b.@

Befunge-93
でオンラインで試すBefunge-98でオンラインで試す

"]"両方のバージョンで文字列リテラルであり、93(ASCII値[)をスタックにプッシュします。'bはBefunge-98の文字リテラルで、98(ASCII値b)をプッシュしますが、Befunge-93では無効な命令であるため、単に無視されます。したがって、Befunge-93のスタックの最上位の93とBefunge-98の98で終わります。.@スタックの一番上に値を書き込み、終了します。


]".@.b'または]g.@.b'仕事
-MildlyMilquetoast

3

Ruby 1.x(<1.9)および2.x、10 8バイト、スコア= 4

$><<?2%7

それを試してみてください:

これは?x、Ruby 1.xと2.xのさまざまな動作を活用することで機能します。Ruby 1.xでは?A(たとえば)65(文字のASCII値)が返されますAが、Ruby 2.0では1文字の文字列が返されます"A"

上記のコードはこれと同等です:

val = ?2
$> << val % 7

Ruby 1.x(<1.9)では、の値val50(文字のASCII値2)、Fixnumです。Fixnum#%はモジュロ演算子なので、を50 % 7返します1

Ruby 2.xでは、valは文字列"2"です。String#%はの挿入語バージョンなsprintfので、"2" % 7と同等です。sprintf("2", 7)ここ"2"で、はフォーマット文字列です。フォーマット文字列にはフォーマットシーケンス(例:)が含まれていないため%d、後続の引数は破棄され"2"て返されます。

最後に$>、はのエイリアスな$stdoutので$> << ...、結果を出力します。


1
いいね!私は?A==66?1:2あなたの答えに出会う前のようなことをしようとしていました
ピッコロ

3

パイソン2及びパイソン336の 34バイトは、スコア18 17

print(str(hash(float('-inf')))[1])

ではPythonの2、負の無限大のハッシュがある-271828が、中にはPython 3それは-314159です。編集:@ArBoのおかげで、2バイト、1ポイントのスコアを保存しました。


斜視これは意図的なe対piのことですか?
ジョーキング

@JoKingはい。明らかにhash、浮動小数点の無限大で動作するように最初に修正されたとき、関連する開発者はハッシュ値としてpi * 1e5およびe * -1e5を使用していました。Python 3のある時点で、負の無限大のhas値は、無限大のハッシュ値の否定になるように変更されました。
ニール

2

Python 3Python 2、スコア17.5

(35バイト、2バージョン)

try:exec("print 2")
except:print(3)

Python 2バイト

オンラインでお試しください!

Python 3バイト

オンラインでお試しください!

ETHproductionsのおかげで5バイト節約

良いコードのゴルフの答えではありませんが、大きな変化です!


うーん、前の行に各ステートメントを置くことができますか?すなわちtry:exec("print 2")\nexcept:print(3)
-ETHproductions

@ETHproductionsありがとう!私は勝つことを期待していなかったので、少し気が散りました。私は主にPython 2と3の間大規模な変更に焦点を当てたかったです。
jferard17年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.