>

저는 코딩 플랫폼에서이 운동에 대한 솔루션에 문제가있는 것으로 일주일 내내 어려움을 겪고 있습니다. 이 시점에서 그것은 포인트를 얻으려고 노력하는 것이 아니라 내 솔루션/추론에서 내가 잘못 된 부분을 이해하는 것입니다.

다음은 과제입니다 :

The walker starts from point O, walks along OA, AB and BC. When he is in C (C will be in the upper half-plane), what is the distance CO? What is the angle tOC in positive degrees, minutes, seconds?

Angle tOA is alpha (here 45 degrees), angle hAB is beta (here 30 degrees), angle uBC is gamma(here 60 degrees).

Task function solve(a, b, c, alpha, beta, gamma) with parameters

a, b, c: positive integers in units of distance alpha, beta, gamma: positive integers in degrees (positive angles are anticlockwise) returns an array

first element: distance CO (rounded to the nearest integer) then angle tOC with the third following elements: second element of the array: number of degrees in angle tOC (truncated positive integer) third element of the array: number of minutes in angle tOC (truncated positive integer) fourth element of the array: number of seconds in angle tOC (truncated positive integer)

여기에 위에서 언급 한 작은 이미지가 있습니다.

기본적으로 각 단계는 직사각형 삼각형을 만듭니다. 내 접근 방식은 사인 규칙을 사용하여 A, B 및 C의 좌표를 점진적으로 찾는 후에 CO와 각도 COt를 쉽게 찾을 수있었습니다. 테스트에 따라 올바른 CO 세그먼트를 얻었지만 각도가 잘못되었습니다.

Test Failed
Expected Array(15, 135, 49, 18), but got Array(15, 143, 2, 45)

Test Failed
Expected Array(20, 141, 4, 23), but got Array(20, 139, 51, 47)

아래에 솔루션을 붙여넣고 사이트에서 테스트 사례를 제공했습니다.

object Walker {
  case class Point(x: Double, y: Double){
    def moveLeft(by: Double) = Point(by - x, y)
    def moveRight(by: Double) = Point(by + x, y)
    def moveUp(by: Double) = Point(x, by + y)
    def moveDown(by: Double) = Point(x, by - y)
    def inverse() = Point(y, x)
  }
  implicit def roundUp(d: Double): Int = math.ceil(d).toInt
  def solve(a: Int, b: Int, c: Int, alpha: Int, beta: Int, gamma: Int): Array[Int] = {
    val pointA = pointHypotenuse(a, alpha)
    val pointB = pointHypotenuse(b, beta).inverse().moveLeft(pointA.x).moveUp(pointA.y)
    val pointC = pointHypotenuse(c, gamma).moveLeft(pointB.x).moveDown(pointB.y)
    val coHypotenuse: Int = math.sqrt(math.pow(pointC.x, 2) + math.pow(pointC.y, 2))
    val sinC = math.sin(math.abs(pointC.x)/coHypotenuse)
    val tOC = 180 - sinC.toDegrees
    coHypotenuse +: degrees(tOC)
  }
  def pointHypotenuse(coteHypotenuse: Int, angleHypotenuse: Int): Point = {
    val sinDuAngle = math.sin(math.toRadians(angleHypotenuse))
    val coteOppose = sinDuAngle * coteHypotenuse
    Point(math.sqrt(math.pow(coteHypotenuse, 2) - math.pow(coteOppose, 2)), coteOppose)
  }
  def degrees(deg: Double): Array[Int] = {
    Stream.iterate((deg.toInt, deg - deg.toInt)){
      case (_, r) =>
        val by60 = r*60
        (by60.toInt, by60 - by60.toInt)
    }.map(_._1).take(3).toArray
  }
}

플랫폼에서 테스트 :

class WalkerTest extends FlatSpec { 
  it should "pass basic tests" in {
    dotest(12, 20, 18, 45, 30, 60, Array(15, 135, 49, 18))
    dotest(15,15,19,50,29,55, Array(12, 133, 18, 44))
    dotest(14,25,17,41,35,59, Array(20, 129, 41, 57))
  }
}
object WalkerTest {
  private def dotest(a: Int, b: Int, c: Int, aa: Int, bb: Int, cc: Int, expect: Array[Int]): Unit = {
    val actual: Array[Int] = Walker.solve(a, b, c, aa, bb, cc)
    assertResult(expect){actual}
  }
}

반올림 오류라고 생각하지 않습니다 (모든 Doubles by Ints 거리 결과가 어설 션의 결과입니다). 일반적으로이 질문을하지는 않지만 실제로 차단 된 것 같습니다.

  • 답변 # 1

    라인

    val sinC = math.sin(math.abs(pointC.x)/coHypotenuse)
    
    

    일부 세그먼트 비율의 사인을 얻지 만이 비율은코사인입니다.
    각도를 얻으려면 arccos 를 사용해야합니다

  • 답변 # 2

    beta(90+given) 의 각도를 전달해야합니다  그리고 gamma(180+given)  모든 각도는 positive x-axis 에서 시계 반대 방향으로 양수를 통과해야합니다. . 그런 다음 moveLeft,moveRight,moveUp,moveDown  그리고 inverse  기능이 필요하지 않은 것 같습니다. 그들 대신에 하나의 함수 moveTo(p:Point) 만 사용할 수 있습니다  클래스 Point 의 경우 이 수정 사항은 아래의 scala REPL에 표시된대로 정확한 테스트 결과를 제공합니다.

    object Walker {
      case class Point(x: Double, y: Double){
        def moveTo(p:Point) = {val t = this.x+p.x;val t1 = this.y+p.y;Point(t,t1) }
      }
      def solve(a: Double, b: Double, c: Double, alpha: Double, beta: Double, gamma: Double):Array[Int]= {
        val pointA = movedPoint(a, alpha)
        val pointB = pointA.moveTo(movedPoint(b,beta))
        val pointC = pointB.moveTo(movedPoint(c,gamma))
        val co = math.sqrt( math.pow(pointC.x, 2) + math.pow(pointC.y, 2))
        val angletOC = Math.asin(math.abs(pointC.y)/co).toDegrees
        val tOC = if(pointC.x<=0 && pointC.y>=0)
            180 - angletOC
        else if(pointC.x<=0 && pointC.y<=0)
            180 + angletOC
        else if(pointC.x>0 && pointC.y<0)
           270 + angletOC
        else angletOC
        Math.round(co).toInt +: convDegMinSec(tOC)
      }
     def movedPoint(dist:Double,angle:Double):Point = {
      val yCo = dist*Math.sin(Math.toRadians(angle))
      val xCo = dist*Math.cos(Math.toRadians(angle))
      Point(xCo,yCo)
     }
     def convDegMinSec(deg: Double): Array[Int] = {
         val degs = deg.toInt
         val mins = (deg - deg.toInt)*60
         val secs =  (mins-mins.toInt)*60
         val arr = Array(degs,mins.toInt,secs.toInt)
         arr
      }
    }
    
    

    스칼라 REPL :

    scala> Walker.solve(12,20,18,45,90+30,180+60)
    res58: Array[Int] = Array(15, 135, 49, 18)
    scala> Walker.solve(15,15,19,50,90+29,180+55)
    res59: Array[Int] = Array(12, 133, 18, 44)
    scala> Walker.solve(14,25,17,41,90+35,180+59)
    res60: Array[Int] = Array(20, 129, 41, 57)
    
    

관련 자료

  • 이전 javascript - 메뉴 링크 클릭시 토글 클래스
  • 다음 HTML - html - dec를 사용하여 알파벳 숫자를 만듭니다 암호