# ホクホクのイモを Delphi で書いてみる --- tags: Delphi programming embarcadero objectpascal ホクホクのイモ created_at: 2019-07-05 updated_at: 2021-03-11 --- # はじめに @mattn さんの [ホクホクのイモ](https://qiita.com/mattn/items/d447a43ad12fada71663) という記事を読んで、これを Dephi で書いてみようと思いました。 # コードを書いてみる ```pascal:hokuimo.dpr uses System.SysUtils, uPermutations; begin Randomize; var s := ''; var rs := 'ホイクモ'; for var i in Perm(4, 2) do s := s + rs.Chars[i]; s := s + s + 'の'; for var i in Perm(4, 2) do s := s + rs.Chars[i]; Writeln(s); end. ``` Delphi だとこんな感じで書け...たらよかったのですが、Perm() というコレクションは標準では存在しません。 ## uPermutations の実装 ランダムな整数のコレクションを返す Perm() を実装してみました。 ```pascal:uPermutations.pas unit uPermutations; interface uses SysUtils, Types, Math; type TPermEnumerator = class; TPerm = record private Fcount: Integer; FIntArr: TIntegerDynArray; public constructor Create(range: Integer; count: Integer); function GetEnumerator: TPermEnumerator; end; TPermEnumerator = class Container: TPerm; Index: Integer; public constructor Create(AContainer : TPerm); function GetCurrent: Integer; function MoveNext: Boolean; property Current: Integer read GetCurrent; end; function Perm(range: Integer; count: Integer): TPerm; overload; function Perm(range: Integer): TPerm; overload; implementation function Perm(range: Integer; count: Integer): TPerm; begin Result := TPerm.Create(range, count); end; function Perm(range: Integer): TPerm; begin Result := TPerm.Create(range, range); end; { TPerm } constructor TPerm.Create(range: Integer; count: Integer); var i, v1, v2: Integer; begin Fcount := Min(count, range); SetLength(FIntArr, range); for i:=0 to Pred(range) do FIntArr[i] := i; for i:=Pred(range) downto 1 do begin v1 := Random(Succ(i)); v2 := FIntArr[i]; FIntArr[i] := FIntArr[v1]; FIntArr[v1] := v2; end; end; function TPerm.GetEnumerator: TPermEnumerator; begin Result := TPermEnumerator.Create(Self); end; { TPermEnumerator } constructor TPermEnumerator.Create(AContainer: TPerm); begin inherited Create; Container := AContainer; Index := -1; end; function TPermEnumerator.GetCurrent: Integer; begin Result := Container.FIntArr[Index]; end; function TPermEnumerator.MoveNext: Boolean; begin result := Index < Pred(Container.Fcount); Inc(Index); end; end. ``` これを使えばホクイモ (ホイクモ?) がシンプルに書けます。 Perm(10) は 0 から 9 までを使った重複しないランダムな整数のコレクションです。 ```pascal for var l := 1 to 10 do begin for var i in Perm(10) do Write(i); Writeln; end; ``` ``` 1964072358 4869207135 2179046853 1865493207 6481953270 0261834957 7354620981 7463251980 6514293087 3498071562 ``` Perm(10, 3) は 0 から 9 までを使ったコレクションのうちの最初の 3 つです。 ```pascal for var l := 1 to 10 do begin for var i in Perm(10, 3) do Write(i); Writeln; end; ``` ``` 437 605 139 570 739 941 042 513 574 982 ``` **See also:** - [for 文を使用したコンテナの反復処理 (DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%E5%AE%A3%E8%A8%80%E3%81%A8%E6%96%87%EF%BC%88Delphi%EF%BC%89#for_.E6.96.87.E3.82.92.E4.BD.BF.E7.94.A8.E3.81.97.E3.81.9F.E3.82.B3.E3.83.B3.E3.83.86.E3.83.8A.E3.81.AE.E5.8F.8D.E5.BE.A9.E5.87.A6.E7.90.86) - [フィッシャー–イェーツのシャッフル (Wikipedia)](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%83%E3%82%B7%E3%83%A3%E3%83%BC%E2%80%93%E3%82%A4%E3%82%A7%E3%83%BC%E3%83%84%E3%81%AE%E3%82%B7%E3%83%A3%E3%83%83%E3%83%95%E3%83%AB) # おわりに Delphi のコレクション集として [Delphi Collection Library (Delphi-Coll) (GitHub)](https://github.com/pavkam/delphi-coll) があります。 **See also:** - [Generic collections library (delphi-coll) (Owl's perspective)](http://owlsperspective.blogspot.com/2011/11/generic-collections-library.html) - [delphi-collを使ってみる(1) (山本隆の開発日誌)](https://www.gesource.jp/weblog/?p=5265) - [delphi-collを使ってみる(2) (山本隆の開発日誌)](https://www.gesource.jp/weblog/?p=5289) - [delphi-collを使ってみる(3) (山本隆の開発日誌)](https://www.gesource.jp/weblog/?p=5290) - [delphi-collを使ってみる(4) (山本隆の開発日誌)](https://www.gesource.jp/weblog/?p=5670) - [delphi-collを使ってみる(5) (山本隆の開発日誌)](https://www.gesource.jp/weblog/?p=6446)