syat

next >>

居眠り床屋問題 (Nested Flatten)
JavaScriptで。マルチスレッドライブラリのConcurrent.Threadを使用しました。
床屋と客の2スレッド構成です。スレッドIDに相当するものはない(と思う)ので、自分で付けました。
寝ていますフラグがないと、床屋が起きているときに notify が飛んで、床屋の機嫌を損ねて(=エラー終了)しまいます。
<実行例>
[床屋] 床屋、眠る
[ 客 ] 来店 1
[床屋] 床屋、目覚める
[床屋] 散髪開始 1
[ 客 ] 来店 2
[ 客 ] 来店 3
[床屋] 散髪完了 1
[床屋] 散髪開始 2
[床屋] 散髪完了 2
[床屋] 散髪開始 3
[ 客 ] 来店 4
[ 客 ] 来店 5
[ 客 ] 来店 6
[ 客 ] 満席で立ち去る 6
[床屋] 散髪完了 3
[床屋] 散髪開始 4
[ 客 ] 来店 7
[ 客 ] 来店 8
[ 客 ] 満席で立ち去る 8
[床屋] 散髪完了 4
[床屋] 散髪開始 5
[床屋] 散髪完了 5
[床屋] 散髪開始 7
[床屋] 散髪完了 7
[床屋] 床屋、眠る
[ 客 ] 来店 9
[床屋] 床屋、目覚める
[床屋] 散髪開始 9
[ 客 ] 来店 10
[ 客 ] 来店 11
[ 客 ] 来店 12
[ 客 ] 満席で立ち去る 12
[床屋] 散髪完了 9
[床屋] 散髪開始 10
[ 客 ] 来店 13
[ 客 ] 来店 14
[ 客 ] 満席で立ち去る 14
[ 客 ] 来店 15
[ 客 ] 満席で立ち去る 15
[床屋] 散髪完了 10
[床屋] 散髪開始 11
[ 客 ] 来店 16
[床屋] 散髪完了 11
[床屋] 散髪開始 13
[床屋] 散髪完了 13
[床屋] 散髪開始 16
[床屋] 散髪完了 16
[床屋] 床屋、眠る
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<html>
<head>
<script type="text/javascript" src="Concurrent.Thread-full-20090713.js"></script>
<script type="text/javascript">
var queue = [];                 //客行列
var barber;                     //床屋スレッド
var customer;                   //客スレッド
var barber_is_sleeping = false; //寝ていますフラグ

//床屋スレッド本体
var barber_func = function() {
  while (true) {
    while (queue.length > 0) {
      var cust = queue[0];
      log(barber, "散髪開始 " + cust.toString());
      Concurrent.Thread.sleep(Math.random()*300+100);
      log(barber, "散髪完了 " + cust.toString());
      queue.shift();
    }
    log(barber, "床屋、眠る");
    try {
      barber_is_sleeping = true;
      stop();
    } catch ( ex ) {
      log(barber, "床屋、目覚める");
      barber_is_sleeping = false;
    }
  }
};
//客スレッド本体
var customer_func = function() {
  var count = 0;

  while (count < 16) {
    count++;
    if (count != 9) {
      Concurrent.Thread.sleep(Math.floor(Math.random()*200));
    } else {
      Concurrent.Thread.sleep(1200);
    }
    log(customer, "来店 " + count.toString());
    if (queue.length >= 3) {
      log(customer, "満席で立ち去る " + count.toString());
    } else {
      queue.push(count);
      if (barber_is_sleeping) {
        barber.notify("wake!");
      }
    }
    yield();
  }
};
//ログ出力
function log(t, s) {
  var o = document.getElementById('result');
  o.innerHTML += '[' + t.ID + '] ' + s + "<br>";
}
function init() {
  barber = Concurrent.Thread.create(barber_func);
  barber.ID = "床屋";
  customer = Concurrent.Thread.create(customer_func);
  customer.ID = " 客 ";
}
</script>
</head>
<body onload="init();">
<div id="result"></div>
</body>
</html>
復活 (Nested Flatten)
VBScript + タスクスケジューラで。
電卓を終了すると約1分後に再起動します。
このスクリプト自体=プロセスAではなく、中で起動するcalc.exeがプロセスAと考えれば、いちおうレベル2です。
最初はJScriptで挑戦しましたが、JobIDを取得するときに参照渡しする方法がわからず断念。JScriptでは不可能???
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
strScriptName = "d:\rebirth"

' アプリを実行する
strAppname = "calc.exe"
WScript.CreateObject("WScript.Shell").Run strAppname, 1, true

strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!//"+strComputer+"/root/cimv2")

Set args = WScript.Arguments
If args.length = 0 Then
  ' 引数なしならタスク登録
  Set objNewJob = objWMIService.Get("Win32_ScheduledJob")
  commandline = "wscript.exe " & strScriptName & "2.js"
  dt = DateAdd( "n", 1, Now )
  oneMinuteLater = Right( 1000000 + Hour(dt)*10000 + Minute(dt)*100 + Second(dt), 6 )
  starttime = "********" & oneMinuteLater & ".000000+540"
  errJobCreated = objNewJob.Create( commandline, starttime, False, 127, "", True, JobID )
  WScript.Echo("タスクを登録しました。" & starttime & "  " & errJobCreated)

  ' サブスクリプト生成
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set tfs = fso.CreateTextFile(strScriptName+"2.js")
  tfs.WriteLine("WScript.CreateObject('WScript.Shell').Run('wscript.exe " & Replace(strScriptName, "\", "\\") & ".vbs " & JobID & "');")
  tfs.Close()
  WScript.Echo("サブスクリプトを生成しました。")

Else
  ' 引数(=ジョブID)があればタスク削除
  JobID = args.Item(0)
  Set objTask = objWMIService.Get("Win32_ScheduledJob.JobID=" & JobID)
  If Err.Number = 0 Then
    objTask.Delete
    WScript.Echo("タスクを削除しました。")
  Else
    WScript.Echo("タスク削除に失敗しました。")
  End If

End If
ラングトンのアリの描画 (Nested Flatten)

C#でビットマップにごりごり描画します。 フレームスキップして速度を稼いでいます。

今回一番はまったのは、Color.FromArgb(255, 0, 0, 0) が Color.Black とイコールではないってこと。ColorはARGB以外の情報を持っているので、ToArgb()で比較するように、とMSDNにある。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace LangtonsAnt {
    class Ant {
        Point pos;
        int direction;
        public int X { get { return pos.X; } }
        public int Y { get { return pos.Y; } }

        public Ant(int x, int y) {
            pos.X = x;
            pos.Y = y;
            direction = 0;
        }
        public void Advance(bool IsBlack) {
            if (IsBlack) {
                direction = (direction + 1) % 4;
            } else {
                direction = (direction + 3) % 4;
            }
            switch (direction) {
                case 0: pos.Y--; break; //北
                case 1: pos.X++; break; //東
                case 2: pos.Y++; break; //南
                case 3: pos.X--; break; //西
            }
        }
    }
    class Form1 : Form {
        Bitmap bitmap;                  //世界=ビットマップ
        List<Ant> ants;                 //アリたち
        Timer timer;                    //タイマー
        long step_count;                //ステップ数
        Color Black = Color.FromArgb(255, 0, 0, 0);
        Color White = Color.FromArgb(255, 255, 255, 255);
        public Form1() {
            //マップの初期化
            this.Width = 300; this.Height = 200;
            bitmap = new Bitmap(300, 200, Graphics.FromHwnd(this.Handle));
            //100,100を中心に黒点を打つ
            Random r = new Random();
            for (int i = 0 ; i < 100 ; i++) {
                int x = r.Next(40) + bitmap.Width / 2 - 20;
                int y = r.Next(40) + bitmap.Height / 2 - 20;
                bitmap.SetPixel(x, y, Black);
            }
            //アリの初期化
            ants = new List<Ant>();
            ants.Add(new Ant(r.Next(20) + bitmap.Width / 2 - 10, r.Next(20) + bitmap.Height / 2 - 10));
            ants.Add(new Ant(r.Next(20) + bitmap.Width / 2 - 10, r.Next(20) + bitmap.Height / 2 - 10));
            ants.Add(new Ant(r.Next(20) + bitmap.Width / 2 - 10, r.Next(20) + bitmap.Height / 2 - 10));
            //タイマー初期化
            step_count = 0;
            timer = new Timer();
            timer.Interval = 300;       //300msに1度再描画
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
        }
        void timer_Tick(object sender, EventArgs e) {
            //高速化のため1描画につき150周回す
            for (int step = 0 ; step < 150 ; step++) {
                foreach (Ant ant in ants) {
                    int x = (ant.X + bitmap.Width) % bitmap.Width;
                    if (x < 0) x += bitmap.Width;
                    int y = (ant.Y + bitmap.Height) % bitmap.Height;
                    if (y < 0) y += bitmap.Height;
                    Color color = bitmap.GetPixel(x, y);
                    if (color == Black) {
                        ant.Advance(true);
                        bitmap.SetPixel(x, y, White);
                    } else {
                        ant.Advance(false);
                        bitmap.SetPixel(x, y, Black);
                    }
                }
            }
            Refresh();
            step_count += 150;
            Text = step_count.ToString();
        }
        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);
            e.Graphics.DrawImage(bitmap, ClientRectangle);
        }
        protected override void OnClosed(EventArgs e) {
            timer.Stop(); timer = null;
            base.OnClosed(e);
        }
    }
    static class Program {
        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
初期設定の読み書き (Nested Flatten)
参考ページを見ると、設定ファイルがなくても設定を読み書きできる方法のことを言っている?
バッチファイルでレジストリの値を取得するコードを書きました。reg.exe呼んでるだけですが。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
===== getreg.bat =====
@echo off
rem reg.exeの結果を1行ごと%rに格納する
for /F "usebackq delims=" %%r in (`reg.exe QUERY %1 /v %2`) do (
  rem %rをタブ区切りデータとみなし、3列目を%tに格納する
  for /F "tokens=3 delims=    " %%t in ("%%r%") do (
    rem %tが空でなければ、レジストリ値だとみなす
    if not "%%t%" == "" (
      echo %%t%
      goto e
    )
  )
)
:e

===== 使用例 caller.bat =====
@echo off
for /F "usebackq delims=" %%v in (`call getreg "HKEY_CURRENT_USER\Control Panel\Desktop" Wallpaper`) do set WALLPAPER=%%v%
echo 壁紙=[%WALLPAPER%]
for /F "usebackq delims=" %%v in (`call getreg "HKEY_CURRENT_USER\Control Panel\Colors" ActiveTitle`) do set ACTIVETITLE=%%v%
echo タイトルバーの色=[%ACTIVETITLE%]

設定ファイルを読み込むお題であれば過去に出ていますが、それとは違くて?

printf書式変換 (Nested Flatten)
COBOL --> Java の移植と言っても、COBOLのプログラムをそのままJavaに翻訳するような無謀なことはしないと思いますよ。
移植するのはデータのみで、COBOLデータを Oracle などの DB に変換したら、あとはSQLでごりごりっとやるJavaプログラムを新たに設計する感じ。
データの移植も各社が出してるパッケージソフトを使ったり、Cで作ったりします。
すみません雑談でした。
手作業Grep (Nested Flatten)
C#で。標準入力とUIを別スレッドにしているので、追加入力可能です。
コマンドラインとUIの組み合わせって意外と新鮮だと思いました。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using System;
using System.Windows.Forms;
using System.Threading;

namespace HandGrep {
    // 行選択ダイアログクラス
    class Dialog : Form {
        ListBox list;
        public ListBox List {
            get { return list; }
            private set { list = value; }
        }
        public Dialog() {
            this.Width = 300; this.Height = 200;
            this.Text = "選択して×ボタンを押してください。";
            this.List = new ListBox();
            this.List.Dock = DockStyle.Fill;
            this.List.SelectionMode = SelectionMode.MultiExtended;
            this.Controls.Add(this.List);
        }
        public void AddLine(string line) {
            this.List.Items.Add(line);
        }
    }
    // メインクラス
    class Program {
        static object objLock;                  // 排他オブジェクト
        static AutoResetEvent evDialogLoad;     // ダイアログ初期化イベント
        static AutoResetEvent evDialogClose;    // ダイアログ終了イベント
        static Dialog dlg;                      // ダイアログ
        delegate void MyDelegate();
 
        static void Main(string[] args) {
            objLock = new object();
            evDialogLoad = new AutoResetEvent(false);
            evDialogClose = new AutoResetEvent(false);

            // ダイアログ作成
            dlg = new Dialog();
            dlg.Load += new EventHandler(       // ダイアログ初期化イベントハンドラ登録
                delegate(object o, EventArgs e) {
                    evDialogLoad.Set();
                });
            // ダイアログを別スレッドで表示
            new MyDelegate(
                delegate() {
                    dlg.ShowDialog();
                }
            ).BeginInvoke(new AsyncCallback(OnDialogClose), null);
            evDialogLoad.WaitOne();             // ダイアログの初期化待ち
            // 標準入力ループ
            string line;
            while ((line = Console.ReadLine()) != null) {
                // 標準入力から1行読み込み、ダイアログに追加
                dlg.Invoke(new MyDelegate(
                    delegate() {
                        lock (objLock) {
                            if (dlg == null) return;
                            dlg.AddLine(line);
                        }
                    }
                ));
            }
            evDialogClose.WaitOne();            // ダイアログの終了待ち
        }
        // ダイアログクローズ後のコールバック
        static void OnDialogClose(IAsyncResult result) {
            lock (objLock) {
                // 選択行を標準出力に書き込む
                foreach (string line in dlg.List.SelectedItems) {
                    Console.WriteLine(line);
                }
                dlg = null;
            }
            evDialogClose.Set();
        }
    }
}
ストレンジアトラクタの描画 (Nested Flatten)
Processing で Rössler attractor を書きました。
アピールポイントは、キー入力で拡大・回転ができるところと、アルファ値が使えるのできれいな絵が描けるところ。
緑の線は赤や青とふるまいが違うのがわかるでしょうか?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
RosslerLine[] lines;
float zoom, rotX, rotY;
void setup() {
  lines = new RosslerLine[3];
  lines[0] = new RosslerLine(0.2, 0.1, 5.7, 1, 1, 1, 0x33FF0000);
  lines[1] = new RosslerLine(0.2, 0.2, 5.7, 1, 1, 1, 0x3300FF00);
  lines[2] = new RosslerLine(0.2, 0.3, 5.7, 1, 1, 1, 0x330000FF);
  size(500, 500, P3D);
  zoom = 7.8;
  rotX = 1.0;
  rotY = -0.8;
  clearScreen();
}
void preDraw() {
  pushMatrix();
  translate(width / 2, height / 2);
  rotateX(rotX);
  rotateY(rotY);
  scale(zoom);
}  
void postDraw() {
  popMatrix();
}
void clearScreen() {
  preDraw();
  background(0);
  stroke(64);  line(0, 0, 0, 30, 0, 0);  // draw x-axis
  stroke(128); line(0, 0, 0, 0, 30, 0);  // draw y-axis
  stroke(192); line(0, 0, 0, 0, 0, 30);  // draw z-axis
  postDraw();
}
void draw() {
  preDraw();
  for (int i = 0; i<lines.length; i++) {
    lines[i].update();
  }
  postDraw();
}
void keyPressed() {
  switch (key) {
  case '+':  zoom += 0.2; break;  // zoom in
  case '-':  zoom -= 0.2; break;  // zoom out
  case ' ':  break;  // clear screen
  case '4':  rotY -= PI / 12; break;  // rotate left or right
  case '6':  rotY += PI / 12; break;  // rotate right or left
  case '8':  rotX -= PI / 12; break;  // rotate up or down
  case '2':  rotX += PI / 12; break;  // rotate down or up
  default :  println("key[" + keyCode + ", " + key + "]"); return;
  }
  clearScreen();
  println("zoom:" + zoom + " rot:(" + rotX + ", " + rotY + ")");
}

class RosslerLine {
  float a = 0.2, b = 0.2, c = 5.7;
  float x = 1.0, y = 1.0, z = 1.0;
  float dt = 0.0015;
  int stepPerFrame = 35;
  int col;
  RosslerLine(float a, float b, float c, float x, float y, float z, int col) {
    this.x = x; this.y = y; this.z = z;
    this.a = a; this.b = b; this.c = c;
    this.col = col;
  }
  void update() {
    stroke(col);
    float x0 = x, y0 = y, z0 = z;
    for (int i = 0; i < stepPerFrame; i++) {
      float dx = ( - y - z ) * dt;
      float dy = ( x + a * y ) * dt;
      float dz = ( b + z * (x - c) ) * dt;
      x += dx; y += dy; z += dz;
    }
    line(x0, y0, z0, x, y, z);
  }
}
16進数から10進数の変換 (Nested Flatten)

書き忘れましたが、扱える整数の幅は符号なし64bitなので、 0 ~ 18446744073709551615 です。

C99にはlong long型があるから簡単じゃん、と思ったら処理系の違いで苦労した。
strtoull で変換し、printf の %ull で出力するのが標準かと。
VC2008EE と gcc(MinGW) で確認しました。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include <stdlib.h>

#ifdef _MSC_VER
  #define strtoull _strtoui64
#endif

#ifdef __MINGW32__
  #define FORMAT_LLU "%I64u"
#else
  #define FORMAT_LLU "%llu"
#endif

int main(void) {
    char buf[128];

    memset(buf, 0x00, sizeof(buf));
    if ( fgets(buf, sizeof(buf), stdin) ) {
        unsigned long long ll;

        ll = strtoull(buf, NULL, 16);

        printf(FORMAT_LLU, ll);
    }
    return 0;
}
ケブンッリジ関数 (Nested Flatten)
qsortにランダム関数をつっこんで大丈夫なのだろうか(無限ループになったりしないかな?)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <stdlib.h>

#define IS_SPACE(c) ( (c) == ' ' || (c) == '\n' )
#define MBCLEN 2

/* ランダム比較関数 */
int compare_random(const void *a, const void *b) {
    return rand() - RAND_MAX / 2;
}

/* ケブンリッジ関数 */
void ciambrgde(char *buf) {
    char *p = buf;

    while (*p) {
        char *word_head;

        /* 空白を読み飛ばす */
        while (IS_SPACE(*p)) { p++; }
        if (! *p) { break; }
        /* 単語の末尾を探す */
        word_head = p;
        while (*p && ! IS_SPACE(*p)) { p += MBCLEN; }
        /* 4文字以上の単語なら入れ替えを行う */
        if ( (p - word_head) >= MBCLEN * 4 ) {
            qsort(word_head + MBCLEN, (p - word_head)/MBCLEN - 2, MBCLEN, compare_random);
        }
    }
    
    return;
}

int main() {
    char buf[] = "こんにちは みなさん おげんき ですか? わたしは げんき です。\n\
この ぶんしょう は いぎりす の ケンブリッジ だいがく の けんきゅう の けっか\n\
にんげん は もじ を にんしき する とき その さしいょ と さいご の もじさえ あっていれば\n\
じゅんばん は めちゃくちゃ でも ちゃんと よめる という けんきゅう に もとづいて\n\
わざと もじの じゅんばん を いれかえて あります。\n\
どうです? ちゃんと よめちゃう でしょ?\n\
ちゃんと よめたら はんのう よろしく";
    
    ciambrgde(buf);
    printf(buf);

    return 0;
}
急勾配の判定 (Nested Flatten)
リストを前から見ていくこともできます。
後ろから見るほうがシンプルだけど、リストの長さが未確定の場合はこちらが有利。
ちなみに [1,0].isHeavySlope() は true になりますが何か?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Array.prototype.isHeavySlope = function() {
    if (this.length == 0) return true;
    var pre, sub;
    for each (var n in this) {
        if (pre == undefined) {
            sub = pre = n;
        } else {
            sub -= n;
            if (pre <= n || sub <= 0) return false;
            pre = n;
        }
    }
    return true;
}
sumの初期値を -∞ にしたらだめじゃん。勘違いです。忘れてください。
てことは [0] は急勾配じゃないということでFA?
効率は悪くないと思うけど、工夫はしてません。

仕様面ではっきりしないのは、
1.空リストは急勾配? not 急勾配?
2.問題文の「空列の和は0とします」をどう読むか。
  [0] は 0 + 空列  なので、not 急勾配になる?
  (sum の初期値を 0 とするか -∞ にするかというだけの話だけど)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Array.prototype.isHeavySlope = function() {
  var sum = 0;
  for (var i = this.length-1; i >= 0; i--) {
    if (this[i] <= sum) return false;
    sum += this[i];
  }
  return true;
}

>>> [].isHeavySlope()
true
>>> [0].isHeavySlope()
false
>>> [1,0].isHeavySlope()
false
>>> [0,1].isHeavySlope()
false
>>> [4,2,1].isHeavySlope()
true
>>> [3,2,1].isHeavySlope()
false
LL Golf Hole 6 - 10進数を2進数に基数変換する (Nested Flatten)

アドレス0に格納されている10進数を2進に変換して表示します。

1
2
3
4
>>>+<<<                               # init
[->>>[-]+>[->[-]+>]+<[<<]<]           # convert into binary
>>>[>>]<<                             # move to the end
[>>+++[->++++[-<<++++>>]<]<.[-]<-<<]  # output
リストを逆順に表示 (Nested Flatten)

アドレス0から連続して文字が格納されている場合。

1
[>]<[.<]>
キッチンタイマー (Nested Flatten)
1
start http://e.ggtimer.com/%1%%20seconds
ローテートシフト (Nested Flatten)
Cで。
64bit整数に2個つめてからシフトしています。
マイナスシフト(左シフト)、32を超えるシフトにも対応。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <stdlib.h>

#ifdef _MSC_VER
    typedef _int32 int32_t;
    typedef _int64 int64_t;
#elif __GNUC__
    #include <stdint.h>
#endif

/* rotate : numをshift回だけ右にローテートシフトする */
int32_t rotate(int32_t num, int shift)
{
    int64_t numnum;
    /* シフト数の正規化(32以下の正数にする) */
    while (shift < 0) shift+= 32;
    shift %= 32;
    /* シフト */
    numnum = num;
    numnum = (numnum<<32) | num;
    return (numnum>>shift) & (int32_t)-1;
}

int main(int argc, char *argv[])
{
    char buf[32+1];
    int32_t num = 0;
    int32_t num2 = 0;
    int shift = 1;

    if (argc < 2) {
        printf("Usage: %s <bits> <shift>\n", argv[0]);
        return EXIT_FAILURE;
    } else if (argc == 2) {
        num = strtol(argv[1], NULL, 2);
    } else if (argc > 2) {
        num = strtol(argv[1], NULL, 2);
        shift = strtol(argv[2], NULL, 10);
    }
    num2 = rotate(num, shift);
    printf("%032s\n", itoa(num2, buf, 2));
    return EXIT_SUCCESS;
}
自分自身を表示する (Nested Flatten)
BASICが動くマシンがないので確認できませんが、DELETE命令、そういえばそんなのありましたね

行番号は0から始まって良いんでしたっけ?私はN88BASIC使いでしたが、0で始めたことは無かったです(大抵100から)

いま手元にあるUBASICだとDELETEも行番号0もダメみたいです。機種やバージョンによって言語仕様がバラバラなのもBASICの特徴。
17歳教 (Nested Flatten)
C#で。
#8519とほとんど同じロジックです
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
class Seventeen {
  public static void Main(String[] args) {
    DateTime dt;
    DateTime now = DateTime.Now;
    DateTime nextMonth = now.AddMonths(1);

    try {
      dt = DateTime.Parse(args[0]);
    } catch {
      Console.WriteLine("時刻を指定してください");
      return;
    }

    Console.WriteLine("今日は{0}", now);
    Console.WriteLine("誕生日は{0}", dt);
    Console.WriteLine("17才と{0}日", (int)(now - dt).TotalDays);

    dt = dt.AddYears(17);

    int month = (now.Year - dt.Year) * 12 + (now.Month - dt.Month);
    int day = now.Day - dt.Day;

    if (day < 0) {
      month--;
      day += DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month);
    }

    Console.WriteLine("17才と{0}ヶ月と{1}日", month, day);
  }
}
next >>

Index

Feed

Other

Link

Pathtraq

loading...