2020年5月5日火曜日

開発環境

入門Goプログラミング (Nathan Youngman(著)、Roger Peppé(著)、吉川 邦夫(監修, 翻訳)、翔泳社)のUNIT 5(状態と振る舞い)、LESSON 22(Goにはクラスがないけれど)の練習問題-2の解答を求めてみる。

コード

package main

import (
 "fmt"
 "math"
)

type coordinate struct {
 d, m, s float64
 h       rune
}

func (c coordinate) decimal() float64 {
 sign := 1.0
 switch c.h {
 case 'S', 'W', 's', 'w':
  sign = -1
 }
 return sign * (c.d + c.m/60 + c.s/3600)
}

type location struct {
 lat, long float64
}

func newLocation(lat, long coordinate) location {
 return location{lat.decimal(), long.decimal()}
}

type world struct {
 radius float64
}

func (w world) distance(p1, p2 location) float64 {
 s1, s2 := math.Sincos(rad(p1.lat))
 c1, c2 := math.Sincos(rad(p2.lat))
 clong := math.Cos(rad(p1.long - p2.long))
 return w.radius * math.Acos(s1*s2+c1*c2*clong)
}
func rad(f float64) float64 {
 return f * math.Pi / 180
}

type landingPoint struct {
 name string
 loc  location
}

func main() {
 mars := world{radius: 3389.5}
 landingPoints := []landingPoint{
  landingPoint{
   "Columbia Memorial Station",
   newLocation(
    coordinate{14, 34, 6.2, 's'},
    coordinate{175, 28, 21.5, 'e'},
   ),
  },
  landingPoint{
   "Challenger Memorial Station",
   newLocation(
    coordinate{1, 56, 46.3, 's'},
    coordinate{354, 28, 24.2, 'e'},
   ),
  },
  landingPoint{
   "Bradbury Landing",
   newLocation(
    coordinate{4, 35, 22.2, 's'},
    coordinate{137, 26, 30.1, 'e'},
   ),
  },
  landingPoint{
   "Elysium Planitia",
   newLocation(
    coordinate{4, 30, 0, 'n'},
    coordinate{135, 54, 0, 'e'},
   ),
  },
 }
 var (
  minDist, maxDist   float64
  minNames, maxNames [2]string
 )
 for i, lp1 := range landingPoints {
  for j := i + 1; j < len(landingPoints); j++ {
   lp2 := landingPoints[j]
   distance := mars.distance(lp1.loc, lp2.loc)
   fmt.Printf("%v - %v 距離 %.2fkm\n",
    lp1.name, lp2.name, distance)
   if minDist == 0 || distance < minDist {
    minDist = distance
    minNames[0] = lp1.name
    minNames[1] = lp2.name
   } else if distance > maxDist {
    maxDist = distance
    maxNames[0] = lp1.name
    maxNames[1] = lp2.name
   }
  }
 }
 fmt.Printf("最も近接している着地点は%vと%v。\n", minNames[0], minNames[1])
 fmt.Printf("最も離れている2点は%vと%v。\n", maxNames[0], maxNames[1])

 earth := world{6371.0008}
 london := newLocation(
  coordinate{51, 30, 0, 'n'},
  coordinate{0, 8, 0, 'w'},
 )
 paris := newLocation(
  coordinate{48, 51, 0, 'n'},
  coordinate{2, 21, 0, 'e'},
 )
 fmt.Printf("英国のロンドンからフランスのパリまでの距離は%.2fkm。\n",
  earth.distance(london, paris))
 mountSharp := newLocation(
  coordinate{5, 4, 48, 's'},
  coordinate{137, 51, 0, 'e'},
 )
 olympusMons := newLocation(
  coordinate{18, 39, 0, 'n'},
  coordinate{226, 12, 0, 'e'},
 )
 fmt.Printf("火星のシャープ山(アイオリス山)からオリンポス山までの距離は%.2fkm。\n",
  mars.distance(mountSharp, olympusMons))
}

入出力結果(Zsh、PowerShell、Terminal)

% go run ./distance.go
Columbia Memorial Station - Challenger Memorial Station 距離 6039.66km
Columbia Memorial Station - Bradbury Landing 距離 6379.28km
Columbia Memorial Station - Elysium Planitia 距離 5948.55km
Challenger Memorial Station - Bradbury Landing 距離 5223.43km
Challenger Memorial Station - Elysium Planitia 距離 5647.02km
Bradbury Landing - Elysium Planitia 距離 5329.54km
最も近接している着地点はChallenger Memorial StationとBradbury Landing。
最も離れている2点はColumbia Memorial StationとBradbury Landing。
英国のロンドンからフランスのパリまでの距離は1203.48km。
火星のシャープ山(アイオリス山)からオリンポス山までの距離は5593.88km。
%

0 コメント:

コメントを投稿