dev || bet-プログラマーとテクノロジーの戦い





犬と猫、ドライバーと歩行者、コカコーラとペプシ、BMWとメルセデス、ソーセージとチーズ、ウズバーとフルーツドリンク、善と悪、結局! しかし、いや、私たちは、いつものように、どのプログラミング言語が優れているかについて議論しました。 パフォーマンスに関する古典的な議論が使用され、誰もチェックしなかったベンチマークへのリンク、年に一度使用する構文パン、人気チャート、1つまたは別の言語を使用する評判の良いプログラマーのリスト...そこに。 さて、20分を超える会話は、ビットコインの価格について議論することになります。



奇妙な方法で、3つのトピックが1つに統合されたため、dev || betのアイデアが生まれました。





プロジェクトの本質



異なるテクノロジーを代表する2人の開発者が同じ問題を解決します。 勝者は、最短時間で解決するか、限られた時間でより良い結果を得る人です。



3人のコメンテーターが参加者の画面でプロセスを見ています。 彼らは解決へのアプローチについて議論し、興味深い瞬間、非標準的な動き、プログラマーが持っている興味深いチップに注目します。 一方、彼らは失敗した決定と失敗に注意を払います。



私たち視聴者は、普通の開発者がどのようにGoogleを考え、間違いを犯し、最終的に決定するかを見たいと思っています。 さらに、ドラッグされたオリンピアードによるアルゴリズムのクリックよりも、ライブラリ関数上のリードのプラグを観察する方が興味深いでしょう。



パイロットリリースでは、参加者として、使用されているテクノロジーを特定した友人と呼んだ:Python vs JavaScript。



最初のリリースの挑戦



2018年にプロジェクトが成功するためには、その名前に必ず暗号通貨またはブロックチェーンを記載する必要があります。 そのため、小さな夢を持って、簡単なタスクを思いつきました。 参加者が受け取った正式な説明は次のようになりました。



今日、誰もが暗号通貨について話しています。 人々が非常に低い価格でビットコインを販売した多くのケースがありました。 まあ、私はかつて150 BTCを15ドルで購入しようと思っていました...

しかし、過去に暗号ブローカーにコマンドを転送できるタイムマシンがあったらどうなるでしょうか? もちろん、グローバルな金融システムをダウンさせるでしょう。 それにもかかわらず、私たちは車を持っている、または少なくとも、私たちはその創造に近いと想像してみましょう。 食べ物のために働いている汚い空腹のフリーランサーであるあなたに、ブローカークライアントのために一連のコマンドを生成するアルゴリズムを作成してほしい。 (もちろん、私たちはもちろん将来の使用のために1年前に作成しました。)



PythonまたはJavaScriptを使用できます。 付属のテストランナーでソリューションを確認してください。 決定がより多くのお金を稼ぐものは、実際のクライアントのためにボットを書くために選ばれます。



API仕様v0.0.18



タスクのランナーは、2つの引数を取る純粋な関数でなければなりません。

prices => [{"btc": 1000}, ...]



- prices => [{"btc": 1000}, ...]



のビットコイン価格の配列

initialSum => 100000



開始残高(米ドル)

関数はコマンドの配列を返す必要があります。 チームは1つずつ呼び出されます。 つまり、14日間、正確に14チームが必要です。

例:

[{"op":"buy","amount":1},{"op":"sell","amount":1}]





チーム:

"buy"



追加属性:金額[浮動]-現在のUSDアカウントを使用してBTCを購入する

追加属性の"sell"



:金額[フロート]-現在のUSDアカウントを使用してBTCを販売する

"pass"



-日をスキップ



タスクの説明は、プロセスをより面白くするために、意図的に混乱させ、曖昧にしています。 確かに、結果として、これは残酷な冗談を演じ、参加者による決定時間を大幅に増加させました。



本質的に、既に知られている価格変更の歴史に従って、ビットコインをいつ買うか、いつ売るか、いつ待つかの指示を与える関数を書く必要がありました。



実装



プラットフォームとしてCodewarsプラットフォームが選択されました。 長い間選んだわけではありませんが、20以上の言語のサポート、シンプルなインターフェイス、参照可能なドラフトタスクを追加する機能など、必要なものがすべて揃っていました。



すでにHabrで書いたcodebattle.hexlet.ioプロジェクトは非常に興味深いようです。 しかし、これまでのところ、相手のコードを見る能力は私たちにとって余計に思えました。



参加者はPythonとJavaScriptを使用したため、テストランナーが実装されました。



Javascript
 'use strict'; const https = require('https'); const currencies = [ 'btc', 'eth', ]; const BASE_CURRENCY = 'usd'; const DEFAULT_CURRENCY = 'btc'; const fetchRates = (days, currency) => new Promise((res, rej) => { https.get(`https://min-api.cryptocompare.com/data/histoday?aggregate=1&e=CCCAGG&extraParams=CryptoCompare&limit=${days}&tryConversion=false&tsym=${BASE_CURRENCY.toUpperCase()}&fsym=${currency.toUpperCase()}`, (resp) => { let data = ''; resp.on('data', (chunk) => { data += chunk; }); resp.on('end', () => { data = JSON.parse(data); data = data.Data; res(data.map(datum => datum['close']).slice(0, -1)); }); }).on("error", err => rej(err)); }); const fetchAllRates = async (days, currencies) => { const prices = {}; for (let currency of currencies) { prices[currency] = await fetchRates(days, currency); } const len = prices[Object.keys(prices)[0]].length; const ret = []; for (let i = 0; i < len; i++) { let price = {}; for (let currency of currencies) { price[currency] = prices[currency][i]; } ret.push(price); } return ret; }; const checkStash = stash => { const vals = Object.values(stash); for (let val of vals) { Test.expect(val >= -Math.pow(10, -6), 'Invalid operation'); if (val < -Math.pow(10, -6)) { throw new Error(`Debts are not supported. Stash: ${JSON.stringify(stash)}`) } } }; const applyTask = (stash, task, prices) => { console.log('- performing task', stash, task, prices); const currency = task.currency || DEFAULT_CURRENCY; switch(task.op) { case 'buy': stash[currency] += task.amount; stash[BASE_CURRENCY] -= task.amount * prices[currency]; break; case 'sell': stash[currency] -= task.amount; stash[BASE_CURRENCY] += task.amount * prices[currency]; break; case 'pass': break; } return stash; }; const runner = async (trader, cases) => { for (let testCase of cases) { let prices = await fetchAllRates(testCase.days, currencies); let stash = testCase.amount; for (let currency of currencies) { stash[currency] = stash[currency] || 0; } console.log(`Testing amount ${stash[BASE_CURRENCY]}, days ${testCase.days}`); let tasks = await trader(prices, stash[BASE_CURRENCY]); for (let i in tasks) { if (!tasks.hasOwnProperty(i)) { continue; } let job = tasks[i]; let todo = job.length ? job : [job]; for (let row of todo) { await applyTask(stash, row, prices[i]); } checkStash(stash); } let result = Math.floor(stash[BASE_CURRENCY] * 100) / 100; console.log(`finished. Resulting amount: ${result}`); } }; runner(trader, [ { amount: { [BASE_CURRENCY]: 100, }, days: 100, }, ]);
      
      







Python
 import urllib2 import json import math currencies = [ 'btc', 'eth', ] BASE_CURRENCY = 'usd' DEFAULT_CURRENCY = 'btc' def fetch_rates(days, currency): data = urllib2.urlopen( 'https://min-api.cryptocompare.com/data/histoday?aggregate=1&e=CCCAGG&extraParams=CryptoCompare&limit={}&tryConversion=false&tsym={}&fsym={}'.format( days, BASE_CURRENCY.upper(), currency.upper())).read() data = json.loads(data)['Data'] return [row['close'] for row in data][:-1] def fetch_all_rates(days, currencies): prices = {currency: fetch_rates(days, currency) for currency in currencies} return [{currency: prices[currency][i] for currency in currencies} for i in range(days)] def check_stash(stash): for currency in stash: test.assert_equals(stash[currency] >= -0.000001, True, 'Invalid operation') if stash[currency] < -0.000001: raise Exception('Debts are not supported. Stash: {}'.format(stash)) def apply_task(stash, task, prices): print '- performing task {} {} {}'.format(stash, task, prices) currency = task['currency'] if 'currency' in task else DEFAULT_CURRENCY if task['op'] == 'buy': stash[currency] += task['amount'] stash[BASE_CURRENCY] -= task['amount'] * prices[currency] elif task['op'] == 'sell': stash[currency] -= task['amount'] stash[BASE_CURRENCY] += task['amount'] * prices[currency] elif task['op'] == 'pass': pass return stash def runner(trader, cases): for testCase in cases: prices = fetch_all_rates(testCase['days'], currencies) stash = testCase['amount'] for currency in currencies: if currency not in stash: stash[currency] = 0 print 'Testing amount {}, days {}'.format(stash[BASE_CURRENCY], testCase['days']) tasks = trader(prices, stash[BASE_CURRENCY]) for i, job in enumerate(tasks): todo = job if isinstance(job, list) else [job] for row in todo: stash = apply_task(stash, row, prices[i]) check_stash(stash) result = math.floor(stash[BASE_CURRENCY] * 100) / 100 print 'finished. Resulting amount: {}'.format(result) runner(trader, [ { "amount": { BASE_CURRENCY: 100, }, "days": 100, } ])
      
      







タスク自体はCodewarsで利用可能です

そして、 Githubの参加者の決定



ご清聴ありがとうございました! あなたのコメント、批判、意見をお待ちしています。



それから何? PHPと JS、.Net vs. Java、iOS vs. Android、React vs. Vue.js?



All Articles