邪悪な目的のための奇妙な選別機


18

こんばんは!

あなたの課題は、一連の数字を完全にソート解除することです。

入力

正確に100個の整数がプログラムに送られます。プログラムは、入力をファイルとして、またはstdinを介して受け入れます。各整数は改行文字で区切られます。

これらの100個の整数は、選択した言語の符号付き整数の最小値から最大値までの範囲になります。

重複する値はありません。値は、順序付けられているか、順序付けられていないか、部分的に順序付けられている可能性があります-プログラムは、各ケースを処理できる必要があります。

出力

出力は、100個の整数で、完全にソートされておらず、それぞれ改行文字で区切られている必要があります。出力は、stdout経由またはファイルへの場合があります。

完全にソートされていないということは、リストが順序付けられた順序で完全にソートされた場合に隣接する値に隣接する値がないことを意味します。

スコア

1文字につき1ポイント、最低スコアが勝ちます。組み込みまたはライブラリの並べ替え機能を使用しないソリューションには、-100のボーナスがあります。組み込みの乱数関数を使用しないソリューションには、-20のボーナスがあります。

この質問をできる限り完全に定義しようとしました。ご質問がある場合は、お問い合わせください。次回の改善方法についてご意見がありましたら、お知らせください。

フォア!


正確に100個の整数の入力があり、重複する値はありません(「入力」を参照)
-lochok

あなたはそうです、それを見つけませんでした。
-Strigoides


非常に多くの巧妙な応答!10月31日8:10-Zulu
lochok

回答:


9

GolfScript(スコア27-120 = -93)

~].,{{.2$<{\}*}*]}*.(;+2%n*

注:$スタック上の要素を参照しています。並べ替えはありますが、手動でコード化されたバブルソートで行われます。

ハワードのおかげで、-90 => -92; -92 => -93に影響を与えたIlmari。


そのような簡潔な答えは信用できますが、(GolfScriptを話せない、または理解していないのでご容赦ください)-^は-100ボーナスから失格しませんか?
lochok

1
@lochok、組み込みの並べ替え関数は$- $プログラム内の並べ替えではないことを述べた理由です(コンテキストに依存します)。プログラムの大部分(42文字のうち28文字)が関数を定義しています^。組み込みソートを使用した最初のバージョンは、14文字のみでした。
ピーターテイラー

ああ-そう。説明をありがとう!
lochok

1
次の出力ループで2つの文字を保存できます2/{~p}%n*
ハワード

1
2/zip~+n*そして.);\+2%n*また、ハワードのバージョン@と文字の同じ数のためにトリックを行います。悲しいかな、私はまだ短いものを見つけることができませんでした。
イルマリカロネン

6

Python -26

(94-120):新しい粗雑なアプローチ。最下位の要素を新しいリストにポップし続けて要素をソートし、繰り返します:

t=l=[]
i=N=100
exec't=t+[input()];'*N+'l+=[t.pop(t.index(min(t)))];'*N+'print l[i%N];i+=3;'*N

Python -13

(107-120):最初のアプローチ:一度に4つの最下位の要素を削除してから、これら4つの要素を別の順序で印刷します。

exec'l=[]'+'+[input()]'*100
while l:
 a,b,c,d=eval('l.pop(l.index(min(l))),'*4)
 for e in[b,d,a,c]:print e

t=l=[]そしてexec't+=[input()];'*100あなたにいくつかの文字を救う
カジモド

また、1つのexecステートメントを複数のループに使用できます。
-quasimodo

@quasimodo私はそのようなことを試みましたが、t=l=[]tとlでは同じオブジェクトを指し、それは動作しません。execただし、括弧をスキップするのはいいことです。
daniero

を使用できますt=t+[input()];。これにより、毎回新しいオブジェクトが作成されます。また、execステートメントで印刷ループを実行することもできます';i+=1;print l[i*3%100]'*100
-quasimodo

あなたは再び正しい。ありがとう!また、%3を削除したり、の繰り返しを避けるなど、他のゴルフを追加しました100
daniero

4

C:11(131〜120)

プログラムはstdinから読み取り、単純な挿入ソートを実行します。その後、他の多くのソリューションと同様に、n番目とn + 50番目の数値を出力します。

main(){int*i,a[101],*j=a;while(scanf("%d",a)>0)for(i=++j;i-->a;)i[1]=*i>=*a?*i:*(i=a);while(a<(i=j-50))printf("%d\n%d\n",*i,*j--);}

3

Mathematica -56 44 4 (95-120)= -25

編集

このバージョンは、リストの並べ替えに組み込み関数もランダム化関数にも依存しません。

Riffle[RotateLeft[#[[All, 2]], 2], #[[All, 1]]] &
[Partition[l //. {x___, a_, b_, y___} /; b < a :> {x, b, a, y}, 2]]

Sort組み込みのソート関数ではありませんか?
ピーターテイラー

あなたは正しいです!ソートに関する制約を逃しました。
DavidC

手巻きのソートを作成しました。
-DavidC

3

J、-63(57-120)文字

他の人はすべて自分で作成したソートルートを進んでいるので...

,50(}.,.{.)($:@([-.m),~m=.]#~]=<./)^:(0<#),".[;._2[1!:1[3

乱数関数も組み込みの並べ替えも使用しません。

単純な再帰選択ソートを使用して、入力をソートします。


3

Ruby 1.9、-59

(61-120)

再帰!実際、これは以前のRubyの試みとは異なり、元の順序に関係なくリストのソートを解除します。

p *(f=->l{l[1]&&f[l-m=l.minmax]+m||[]})[$<.map &:to_i].rotate

以前の試み

キュートなワンライナー、組み込みソートを使用して適切に動作するようになりました:

$<.map(&:to_i).sort.each_slice(4){|a,b,c,d|p b,d,a,c}

最初の1つ-最後の4つの値を必ずしもソート解除しなかった:

l=$<.map &:to_i
48.times{l-=p *l.minmax}
a,b,c,d=l
p b,d,a,c

1
-72ソリューションは、リストがソートされた状態で開始されることを想定していますが、そうではありません。
histocrat

おっとっと。私がこの質問を再訪したとき、私は質問を徹底的に読み直さなかったようです。他の何かを考え出そうとします。
ダニエロ

それを行う必要があります@histocrat。
daniero

1

Python 2:90文字

n=100
s=sorted(int(raw_input())for i in range(n))
for i in range(n):print s[(4*i+4*i/n)%n]

怠zyな試みが、初心者向け


1

Python 48 =(148-100)

from random import*
x=[input()for i in range(100)]
while any(abs(x[i]-x[i+1])>1 for i in range(99)):n=randint(1,99);x=x[n:]+x[:n]
for j in x:print j

これをテストしていないのは、妥当な時間内に実行することが保証されていない(またはそうでない)ためですが、理論上は無限の時間で動作するはずです。


1
x=map(input,['']*100)
-ugoren

そして、あなたは余分な[]s さえ必要とは思わず、ただ一つの文字列です。
仕事

1

Python 27(147-100-100)

R=range
def S(L):
 for i in R(len(L)-1):
    if L[i]>L[i+1]:L[i:i+2]=[L[i+1],L[i]];S(L)
a=map(input,['']*100);S(a)
for i in R(100):print a[i/2+i%2*50]

注:前のスペースif L[i]>...はタブである必要がありますが、コードブロックではスペースとして表示されます。


R=rangeあなたが5つの文字を救うことができます。
スクリーバー

a=map(input,['']*100)
ウゴレン

1

Perl 5:95-120 = -25文字

次のコマンドラインをカウントします。

perl -ne '$n=$_;splice@n,(grep{$n[$_]>$n}0..@n),0,$n}{print for map{@n[$_,$#n/2+$_+1]}0..$#n/2'

1

ルビー:-50(70文字-120)

他の多くの回答と同じように、入力リストからmaxとminを繰り返し削除し、出力に追加しました。ただし、中央値の両側の2つの数字が連続している場合、出力が正しくないことに気付きました(これらの2つの連続した数字が出力の最後に一緒に表示されるため)。これを修正するために、「ソートされていない」リストを右に1要素ずつ回転させます。

n=$*.map &:to_i;u=[];50.times{u+=n.minmax;n-=u.last 2};p *u.rotate(-1)

または、任意の多くの入力を処理するには(さらに4文字のみを使用):

n=$*.map &:to_i;u=[];(u+=n.minmax;n-=u.last 2)while n.any?;p *u.rotate(-1)

注:いくつかの文字数の少ないRubyの回答が既に投稿されていますが、これらのソリューションは中央値の問題に対処していません(および/またはソートされた入力リストを想定しています)。


1

J 37-100 = -63

({~?~@#)^:(+./@(1=|)@(2&(-/\))@/:)^:_

ソートを使用しません(ランクアップは使用します)乱数を使用します。

説明:

({~?~@#)             NB. Randomizes the array
^: foobar ^:_        NB. as long as
foo =: +./@(1 = |)   NB. as any 1 == absolute value of
bar =: (2&(-/\))@/:  NB. differences between adjacent ranks
foobar =: foo@bar

1

Brachylog、22バイト-120 = -98

ṇịᵐpX¬{p≤₁s₂.&s₂p}∧Xẉᵐ

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

TIOリンクには100ではなく8個の整数の入力しかありません。これは非常に遅いため、60秒以内に処理できなくなります。この理由は、決定論的ボゴソートに相当するものを使用簡潔にするために、私の必須のボーナスのためのいくつかの単純だが、通常のソートアルゴリズムを実装するのではなく、他のものの間で、それであるp≤₁それが見つかるまで、入力のすべての順列によるバックトラック減少していません。より大きな理由はおそらく、出力を見つけるために同じ程度のブルートフォースを使用し、毎回ソートされたバージョンを再計算することです...私はサイズ100の実際の入力でテストしようとしましたが、私は何日かかるかわかりません。

全体的に改善されたバージョン:

Brachylog、14バイト-20 = -6

p.¬{os₂.&s₂p}∧

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

これは簡潔さのために時代遅れのI / O要件を無視し、スーパーコンピューターなしでテストできるように-100ボーナスを取ることを怠っています(これを書いている時点では、20項目で数分間実行していましたが、まだ何も与えていない)。

 .                The output is
p                 a permutation of
                  the input
  ¬{        }∧    such that it cannot be proven that
         s₂       a pair of adjacent values in
        &         the output
       .   p      is a permutation of
     s₂           a pair of adjacent values in
    o             the output sorted.

これは正確な実用的な答えではありませんが、他のプログラムからの出力の検証に役立つ可能性があります。ほとんどの場合、出力に課せられた制約を記述しているだけです。
20:36の無関係な文字列

0

Forth(gforth)79-120 = -21バイト

: f 100 0 do dup i 2 mod 4 * 2 - i + i 99 = i 0 = - 3 * + cells + @ . cr loop ;

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

時代遅れの入力要件を無視し、数値が格納されているメモリ内のアドレスとして入力を受け取ります。

説明

0から99までのすべての数値をループします。各数値(n)に対して:

  • nが0の場合:
    • 配列アドレス+ 1の値を出力します
  • それ以外の場合、nが99の場合:
    • 配列アドレス+ 98の値を出力します
  • それ以外の場合nが奇数の場合:
    • 配列アドレス+(n + 2)の値を出力します
  • その他(nは偶数):

    • 配列アドレス+(n-2)の値を出力します
  • 改行を出力する

コードの説明

: f               \ start new word definition
  100 0 do        \ loop from 0 to 99
    dup           \ duplicate the array address
    i             \ place the loop index on the stack
    2 mod 4 * 2 - \ convert to 2 if it's odd and -2 if it's even
    i +           \ add the result to the the loop index
    i 99 =        \ if i = 99 place -1 on top of the stack, else place a 0
    i 0 =         \ i i = 0 place -1 on top of the stack, else place 0
    - 3 *         \ subtract previous two results from each other and multiply by 3
\ the above line is used to avoid writing if/then by instead using math to get 98 and 1
    +             \ add result to existing result from above
    cells         \ multiply by the size of a single integer in memory
    +             \ add to the array's starting address
    @ . cr        \ get the value at the calculated address, print it, then print a newline
  loop            \ end the loop
;                 \ end the word definition
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.