challenge データの整列

(x, y) の座標情報を以下の2種類の方法で整列する機能を実現してください。

  • (x, y) の辞書順(まず x で昇順に整列して、x が同じデータに対して y で昇順に整列する)
  • (0, 0) からの距離の昇順

データの表現方法はタプルなり構造体/オブジェクトなり各自で適当に選んで下さい。

Posted feedbacks - Ruby

別に面白いことは何もありませんが、普通に。
   pairlist = []
   10.times { pairlist.push(LexicalPair.new(rand(10), rand(10))) }
   puts pairlist.sort
とかして遊びます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Pair
  attr_reader :x, :y
  def initialize(x,y)
    @x, @y = x, y
  end
  def to_s
    "(#{@x},#{@y})"
  end
end

class LexicalPair < Pair
  include Comparable
  def <=>(p)
    @x == p.x ? @y <=> p.y : @x <=> p.x
  end
end

class PolarPair < Pair
  include Comparable
  def <=>(p)
    (@x**2 + @y**2) <=> (p.x**2 + p.y**2)
  end
end

Ruby です。

set = [ [ 1, 2 ], [ 1, 3 ], [ 2, 8 ], [ 9, 5 ], [ 6, 8 ], [ 0, 2 ] ]
include Coord
p sort_lexical( set )
p sort_distance( set )
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
module Coord
  def sort_lexical coords
    coords.sort do | a, b |
      if a[ 0 ] == b[ 0 ]
        a[ 1 ] <=> b[ 1 ]
      else
        a[ 0 ] <=> b[ 0 ]
      end
    end
  end


  def sort_distance coords
    coords.sort do | a, b |
      a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] <=> b[ 0 ] * b[ 0 ] + b[ 1 ] * b[ 1 ]
    end
  end
end

すいません言語指定し忘れました。 Rubyです。


任意のn次元の座標に対応しています. zipメソッドのためにeachメソッドを定義してEnumerableをインクルードしているためにちょっと大がかりになっています. 大がかりついでにinspectも再定義してpメソッドで適切に出力されるようにしてみました.

 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
class CoordSet
  def initialize(coord_set)
    @coord_set = coord_set.map{|c| Coord.new(c)}
  end
  def sort_by(order=nil)
    lex_compare = proc{|c0,c1|
      c0.zip(c1).each{|e0,e1| break e0 <=> e1 unless e0 == e1}}
    case order
    when 'lexical' then block = proc{|a,b| lex_compare.call(a,b)}
    when 'linear'  then block = proc{|a,b| a.size == b.size ?
        lex_compare.call(a,b) : a.size <=> b.size}
    else block = proc{|a,b| a <=> b}
    end
    @coord_set.sort(&block)
  end
end
class Coord
  include Enumerable
  def initialize(coord) @coord = coord end
  #
  def size() @coord.map{|x| x.to_i**2}.inject(0){|a,b| a+b} end
  #
  def inspect() @coord end
  #
  def each(&block) @coord.each(&block) end
end
set = [[0, 9], [1, 2], [1, 3], [2, 8], [9, 5], [6, 8], [0, 2]]
cs = CoordSet.new(set)
p cs.sort_by('lexical')
  #=> [[0, 2], [0, 9], [1, 2], [1, 3], [2, 8], [6, 8], [9, 5]]
p cs.sort_by('linear')
  #=> [[0, 2], [1, 2], [1, 3], [2, 8], [0, 9], [6, 8], [9, 5]]

Index

Feed

Other

Link

Pathtraq

loading...