Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-06-04

DylanでL-99 (P09 連続して現われる要素を纏める)

| 19:25 | DylanでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる を含むブックマーク はてなブックマーク - DylanでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる

Perlのjoin的なものがないので、自作してみました。

なんだか無闇に長い…。

#(a:, a:, a:, a:, b:, c:, c:, a:, a:, d:, e:, e:, e:, e:).pack
//=>#(#(#"a", #"a", #"a", #"a"), #(#"b"), #(#"c", #"c"), #(#"a", #"a"), #(#"d"), #(#"e", #"e", #"e", #"e"))
#[a:, a:, a:, a:, b:, c:, c:, a:, a:, d:, e:, e:, e:, e:].pack
//=> #[#(#"a", #"a", #"a", #"a"), #(#"b"), #(#"c", #"c"), #(#"a", #"a"), #(#"d"), #(#"e", #"e", #"e", #"e")]
"aaaabccaadeeee".pack
//=> "aaaa,b,cc,aa,d,eeee"

// Code
module: l99-09

define generic pack
    (sequence :: <sequence>)
 => (result :: <sequence>);

define method pack
    (sequence :: <string>)
 => (result :: <string>)
  if (sequence.empty?)
    sequence
  else
    join(sequence.pack1, ",")
  end if
end method pack;

define method pack
    (sequence :: <sequence>)
 => (result :: <sequence>)
  if (sequence.empty?)
    sequence
  else
    as(select (sequence by instance?)
         <list> => <list>;
         <vector> => <vector>;
       end select, sequence.pack1) 
  end if
end method pack;

define function pack1
    (sequence :: <sequence>)
 => (result :: <sequence>)
  let prev = sequence.first;
  let res = make(<deque>);
  let tem = make(<deque>);
  for (x in sequence)
    unless (x = prev)
      push-last(res, as(<list>, tem));
      tem := make(<deque>);
    end unless;
    push-last(tem, x);
    prev := x;
  end for;
  as(<list>, push-last(res, as(<list>, tem)));
end function pack1;

define generic join 
    (sequence :: <sequence>, delim :: <string>)
 => (result :: <sequence>);

define method join 
    (sequence :: <sequence>, delim :: <string>)
 => (result :: <string>)
  let result = make(<deque>);
  for (c in sequence)
    push-last(result, c);
    push-last(result, delim);
  finally
    result.pop-last;
    apply(concatenate-as, <string>, result);
  end for
end method join;

pfcでL-99 (P09 連続して現われる要素を纏める)

| 04:20 | pfcでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる を含むブックマーク はてなブックマーク - pfcでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる

うーん、これだ!というようなpfcでの良い書き方がありそうな気がする問題ではあるのですが、全然思い付けません。

(pack '(a a a a b c c a a d e e e e))
;==> [[a a a a] [b] [c c] [a a] [d] [e e e e]]

(define (pack lst)
  (if (null lst)
      ()
      (pack1 lst () ())))

(define (pack1 lst tem res)
  (let ((head (hd lst))
        (tail (tl lst)))
    (if (consp tail)
        (if (= head (hd tail))
            (pack1 tail 
                   (++ [head] tem)
                   res)
            (pack1 tail 
                   ()
                   (++ res [(cons head tem)])))
        (++ res [(cons head tem)]))))