Help us understand the problem. What is going on with this article?

tcl リスト操作関数による回転

まえがき

接頭辞がlで始まる関数を使ってリスト操作してみた。

参考文献

https://wiki.tcl-lang.org/page/for
https://blog.it-see.net/it-dokata/tcl-tk/data-structure/

環境

$tclsh
% info tclversion
8.5

スクリプト

3つ。

1.left_stair.sh

先頭要素取得して末尾要素に追加していくパターン。

$cat left_stair.tcl
#!/usr/bin/tclsh

proc usage {} {
  puts "

Usage:

  "
  exit 1
}

proc chk_args {argc argv} {
  if {$argc!=0} {
    set input $argv
    if {[string length $input]==0} {
      usage
    }
    set input_done "[split [lindex $input 0] "\n"] {}"
    set input_done_done [lrange $input_done 0 end-1]
    set init_args "\{$input_done_done\}"
    return $init_args
  } else {
    set stdin [open "| cat -"]
    set input [read $stdin]
    if {[string length $input]==1} {
      usage
    }
    set input_done "[split $input "\n"]"
    set input_done_done [lrange $input_done 0 end-1]
    set init_args "\{$input_done_done\}"
    return $init_args
  }
}

proc circle {rsv_args} {
  #https://wiki.tcl-lang.org/page/for
  set init_args $rsv_args
  for {set ind 0} {$ind < [llength [lindex $rsv_args 0]]} {incr ind} {
    set ele [lindex [lindex $init_args 0] 0] ;#先頭要素フェッチ[shift]
    set init_args "\{[lrange [lindex $init_args 0] 1 end]\}";#先頭要素以外取得
    set init_args "\{[linsert [lindex $init_args 0] end $ele]\}";#先頭要素を末尾に追加[push]
    puts $init_args
  }
}

proc main {argc argv} {
  #スコープはかぶらない。ファンクション内で閉じている。
  set init_args [chk_args $argc $argv]
  circle $init_args
}

main $argc $argv

先頭要素が次の対象行の末尾要素に追加されていく様子がわかる。

$./left_stair.tcl "$(echo {a..e}|xargs -n1)"
{b c d e a}
{c d e a b}
{d e a b c}
{e a b c d}
{a b c d e}
$./left_stair.tcl "$(echo {a..e}|xargs -n2)"
{{c d} e {a b}}
{e {a b} {c d}}
{{a b} {c d} e}
$./left_stair.tcl "$(echo {a..j}|xargs -n2)"
{{c d} {e f} {g h} {i j} {a b}}
{{e f} {g h} {i j} {a b} {c d}}
{{g h} {i j} {a b} {c d} {e f}}
{{i j} {a b} {c d} {e f} {g h}}
{{a b} {c d} {e f} {g h} {i j}}
$echo {a..l} |xargs -n4 | ./left_stair.tcl
{{e f g h} {i j k l} {a b c d}}
{{i j k l} {a b c d} {e f g h}}
{{a b c d} {e f g h} {i j k l}}

2.right_stair.sh

末尾要素取得して先頭要素に追加していくパターン。

$cat right_stair.tcl
#!/usr/bin/tclsh

proc usage {} {
  puts "

Usage:

  "
  exit 1
}

proc chk_args {argc argv} {
  if {$argc!=0} {
    set input $argv
    if {[string length $input]==0} {
      usage
    }
    set input_done "[split [lindex $input 0] "\n"] {}"
    set input_done_done [lrange $input_done 0 end-1]
    set init_args "\{$input_done_done\}"
    return $init_args
  } else {
    set stdin [open "| cat -"]
    set input [read $stdin]
    if {[string length $input]==1} {
      usage
    }
    set input_done "[split $input "\n"]"
    set input_done_done [lrange $input_done 0 end-1]
    set init_args "\{$input_done_done\}"
    return $init_args
  }
}

proc circle {rsv_args} {
  #https://wiki.tcl-lang.org/page/for
  set init_args $rsv_args
  for {set ind 0} {$ind < [llength [lindex $rsv_args 0]]} {incr ind} {
    set ele [lindex [lindex $init_args 0] end] ;#末尾要素フェッチ[pop]
    set init_args "\{[lrange [lindex $init_args 0] 0 end-1]\}";#末尾要素以外取得
    set init_args "\{[linsert [lindex $init_args 0] 0 $ele]\}";#末尾要素を先頭要素に追加[unshift]
    puts $init_args
  }
}

proc main {argc argv} {
  #スコープはかぶらない。ファンクション内で閉じている。
  set init_args [chk_args $argc $argv]
  circle $init_args
}

main $argc $argv

末尾要素が先頭要素に追加されていく様子がわかる。

$./right_stair.tcl "$(echo {a..e}|xargs -n1)"
{e a b c d}
{d e a b c}
{c d e a b}
{b c d e a}
{a b c d e}
$./right_stair.tcl "$(echo {a..e}|xargs -n2)"
{e {a b} {c d}}
{{c d} e {a b}}
{{a b} {c d} e}
$./right_stair.tcl "$(echo {a..j}|xargs -n2)"
{{i j} {a b} {c d} {e f} {g h}}
{{g h} {i j} {a b} {c d} {e f}}
{{e f} {g h} {i j} {a b} {c d}}
{{c d} {e f} {g h} {i j} {a b}}
{{a b} {c d} {e f} {g h} {i j}}
$echo {a..l} |xargs -n4 | ./left_stair.tcl
{{e f g h} {i j k l} {a b c d}}
{{i j k l} {a b c d} {e f g h}}
{{a b c d} {e f g h} {i j k l}}

3.square.sh

上記スクリプトをそれぞれ左と右、右と左に並びて、与える引数を正順と逆順の2つにしたパターン。

$cat square.sh
#!/bin/bash

usage(){
  cat <<EOF
Usage:
\$$0 \$(echo -e '\U1f4a'{0..9})
\$$0 \$(echo '\U304'{1..9})
EOF
}

chk_args(){
  declare -a argv=()
  local argv=($@)
  local argc="${#argv[@]}"
  [ "${argc}" -le 2 ] && usage && exit 1
}

circle(){
  local grp="$1";shift
  local args="$@";shift
  paste -d' ' <(echo "${args}" | xargs -n"${grp}" | ./left_stair.tcl) <(echo "${args}" | rev | xargs -n"${grp}" | ./right_stair.tcl)
  paste -d' ' <(echo "${args}" | xargs -n"${grp}" | ./right_stair.tcl) <(echo "${args}" | rev | xargs -n"${grp}" | ./left_stair.tcl)
}

main(){
  local init_args="$(cat -)";
  chk_args "${init_args}"
  while read grp args;do circle "${grp}" "${args}";done <<<"${init_args}"
}

[ -p /dev/stdin ] && cat - | main
[ -p /dev/stdin ] || echo -ne "$@" | main

引数も簡略化できていいかんじ

$./square.sh 1 {a..e}
{b c d e a} {a e d c b}
{c d e a b} {b a e d c}
{d e a b c} {c b a e d}
{e a b c d} {d c b a e}
{a b c d e} {e d c b a}
{e a b c d} {d c b a e}
{d e a b c} {c b a e d}
{c d e a b} {b a e d c}
{b c d e a} {a e d c b}
{a b c d e} {e d c b a}
$./square.sh 2 {a..e}
{{c d} e {a b}} {a {e d} {c b}}
{e {a b} {c d}} {{c b} a {e d}}
{{a b} {c d} e} {{e d} {c b} a}
{e {a b} {c d}} {{c b} a {e d}}
{{c d} e {a b}} {a {e d} {c b}}
{{a b} {c d} e} {{e d} {c b} a}
$./square.sh 2 {a..j}
{{c d} {e f} {g h} {i j} {a b}} {{b a} {j i} {h g} {f e} {d c}}
{{e f} {g h} {i j} {a b} {c d}} {{d c} {b a} {j i} {h g} {f e}}
{{g h} {i j} {a b} {c d} {e f}} {{f e} {d c} {b a} {j i} {h g}}
{{i j} {a b} {c d} {e f} {g h}} {{h g} {f e} {d c} {b a} {j i}}
{{a b} {c d} {e f} {g h} {i j}} {{j i} {h g} {f e} {d c} {b a}}
{{i j} {a b} {c d} {e f} {g h}} {{h g} {f e} {d c} {b a} {j i}}
{{g h} {i j} {a b} {c d} {e f}} {{f e} {d c} {b a} {j i} {h g}}
{{e f} {g h} {i j} {a b} {c d}} {{d c} {b a} {j i} {h g} {f e}}
{{c d} {e f} {g h} {i j} {a b}} {{b a} {j i} {h g} {f e} {d c}}
{{a b} {c d} {e f} {g h} {i j}} {{j i} {h g} {f e} {d c} {b a}}
$./square.sh 3 {a..j}
{{d e f} {g h i} j {a b c}} {a {j i h} {g f e} {d c b}}
{{g h i} j {a b c} {d e f}} {{d c b} a {j i h} {g f e}}
{j {a b c} {d e f} {g h i}} {{g f e} {d c b} a {j i h}}
{{a b c} {d e f} {g h i} j} {{j i h} {g f e} {d c b} a}
{j {a b c} {d e f} {g h i}} {{g f e} {d c b} a {j i h}}
{{g h i} j {a b c} {d e f}} {{d c b} a {j i h} {g f e}}
{{d e f} {g h i} j {a b c}} {a {j i h} {g f e} {d c b}}
{{a b c} {d e f} {g h i} j} {{j i h} {g f e} {d c b} a}
$echo 13 {a..z} | ./square.sh
{{n o p q r s t u v w x y z} {a b c d e f g h i j k l m}} {{m l k j i h g f e d c b a} {z y x w v u t s r q p o n}}
{{a b c d e f g h i j k l m} {n o p q r s t u v w x y z}} {{z y x w v u t s r q p o n} {m l k j i h g f e d c b a}}
{{n o p q r s t u v w x y z} {a b c d e f g h i j k l m}} {{m l k j i h g f e d c b a} {z y x w v u t s r q p o n}}
{{a b c d e f g h i j k l m} {n o p q r s t u v w x y z}} {{z y x w v u t s r q p o n} {m l k j i h g f e d c b a}}
$echo -e 1 '\U304'{1..9} | ./square.sh
{あ ぃ い ぅ う ぇ え ぉ ぁ} {ぁ ぉ え ぇ う ぅ い ぃ あ}
{ぃ い ぅ う ぇ え ぉ ぁ あ} {あ ぁ ぉ え ぇ う ぅ い ぃ}
{い ぅ う ぇ え ぉ ぁ あ ぃ} {ぃ あ ぁ ぉ え ぇ う ぅ い}
{ぅ う ぇ え ぉ ぁ あ ぃ い} {い ぃ あ ぁ ぉ え ぇ う ぅ}
{う ぇ え ぉ ぁ あ ぃ い ぅ} {ぅ い ぃ あ ぁ ぉ え ぇ う}
{ぇ え ぉ ぁ あ ぃ い ぅ う} {う ぅ い ぃ あ ぁ ぉ え ぇ}
{え ぉ ぁ あ ぃ い ぅ う ぇ} {ぇ う ぅ い ぃ あ ぁ ぉ え}
{ぉ ぁ あ ぃ い ぅ う ぇ え} {え ぇ う ぅ い ぃ あ ぁ ぉ}
{ぁ あ ぃ い ぅ う ぇ え ぉ} {ぉ え ぇ う ぅ い ぃ あ ぁ}
{ぉ ぁ あ ぃ い ぅ う ぇ え} {え ぇ う ぅ い ぃ あ ぁ ぉ}
{え ぉ ぁ あ ぃ い ぅ う ぇ} {ぇ う ぅ い ぃ あ ぁ ぉ え}
{ぇ え ぉ ぁ あ ぃ い ぅ う} {う ぅ い ぃ あ ぁ ぉ え ぇ}
{う ぇ え ぉ ぁ あ ぃ い ぅ} {ぅ い ぃ あ ぁ ぉ え ぇ う}
{ぅ う ぇ え ぉ ぁ あ ぃ い} {い ぃ あ ぁ ぉ え ぇ う ぅ}
{い ぅ う ぇ え ぉ ぁ あ ぃ} {ぃ あ ぁ ぉ え ぇ う ぅ い}
{ぃ い ぅ う ぇ え ぉ ぁ あ} {あ ぁ ぉ え ぇ う ぅ い ぃ}
{あ ぃ い ぅ う ぇ え ぉ ぁ} {ぁ ぉ え ぇ う ぅ い ぃ あ}
{ぁ あ ぃ い ぅ う ぇ え ぉ} {ぉ え ぇ う ぅ い ぃ あ ぁ}

あとがき

絵文字で遊べるかが課題。

以上、ありがとうございました。

20191113追記

キタ----------------

$echo -e 1 '\U1f4a'{1..9} | ./square.sh
{💢 💣 💤 💥 💦 💧 💨 💩 💡} {💡 💩 💨 💧 💦 💥 💤 💣 💢}
{💣 💤 💥 💦 💧 💨 💩 💡 💢} {💢 💡 💩 💨 💧 💦 💥 💤 💣}
{💤 💥 💦 💧 💨 💩 💡 💢 💣} {💣 💢 💡 💩 💨 💧 💦 💥 💤}
{💥 💦 💧 💨 💩 💡 💢 💣 💤} {💤 💣 💢 💡 💩 💨 💧 💦 💥}
{💦 💧 💨 💩 💡 💢 💣 💤 💥} {💥 💤 💣 💢 💡 💩 💨 💧 💦}
{💧 💨 💩 💡 💢 💣 💤 💥 💦} {💦 💥 💤 💣 💢 💡 💩 💨 💧}
{💨 💩 💡 💢 💣 💤 💥 💦 💧} {💧 💦 💥 💤 💣 💢 💡 💩 💨}
{💩 💡 💢 💣 💤 💥 💦 💧 💨} {💨 💧 💦 💥 💤 💣 💢 💡 💩}
{💡 💢 💣 💤 💥 💦 💧 💨 💩} {💩 💨 💧 💦 💥 💤 💣 💢 💡}
{💩 💡 💢 💣 💤 💥 💦 💧 💨} {💨 💧 💦 💥 💤 💣 💢 💡 💩}
{💨 💩 💡 💢 💣 💤 💥 💦 💧} {💧 💦 💥 💤 💣 💢 💡 💩 💨}
{💧 💨 💩 💡 💢 💣 💤 💥 💦} {💦 💥 💤 💣 💢 💡 💩 💨 💧}
{💦 💧 💨 💩 💡 💢 💣 💤 💥} {💥 💤 💣 💢 💡 💩 💨 💧 💦}
{💥 💦 💧 💨 💩 💡 💢 💣 💤} {💤 💣 💢 💡 💩 💨 💧 💦 💥}
{💤 💥 💦 💧 💨 💩 💡 💢 💣} {💣 💢 💡 💩 💨 💧 💦 💥 💤}
{💣 💤 💥 💦 💧 💨 💩 💡 💢} {💢 💡 💩 💨 💧 💦 💥 💤 💣}
{💢 💣 💤 💥 💦 💧 💨 💩 💡} {💡 💩 💨 💧 💦 💥 💤 💣 💢}
{💡 💢 💣 💤 💥 💦 💧 💨 💩} {💩 💨 💧 💦 💥 💤 💣 💢 💡}

以下簡易ビルド手順。

TkinterでUnicode絵文字を表示する
emoji

curl -LO https://prdownloads.sourceforge.net/tcl/tcl8.6.9-src.tar.gz
tar xvf tcl8.6.9-src.tar.gz
cd tcl8.6.9
export CFLAGS=-DTCL_UTF_MAX=6
export MAKEFLAGS=-j5
./configure --prefix=/usr/local --enable-threads --enable-shared --enable-symbols --enable-64bit --enable-langinfo --enable-man-symlinks
make
sudo make install
sudo ln -fns /home/sqlite/tcl8.6.9/unix/tclsh /usr/local/bin/tclsh
$which tclsh
/usr/local/bin/tclsh

$tclsh
% info tclversion
8.6
ukijumotahaneniarukenia
sqlが大好き。(oracle) WordPressはじめました。sql oracleやそれ以外について調べたこととか記していきます。 https://github.com/ukijumotahaneniarukenia
https://ukijumotahaneniarukenia.site/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした