1P5: Động đất!


13

Máy đo địa chấn của USGS vừa phát hiện một trận động đất lớn! Các đội phản ứng khẩn cấp cần ước tính nhanh về số lượng người bị ảnh hưởng. Viết chương trình tính toán ước tính này.

Chương trình của bạn nhận được 2 đầu vào. Đầu tiên là các chi tiết của trận động đất. Trận động đất được mô phỏng như một đoạn đường dọc theo đó trái đất bị vỡ, cùng với khoảng cách tới hạn từ sự cố có thể xảy ra thiệt hại. Đầu vào thứ hai là một danh sách các vị trí và dân số của các thành phố trong khu vực. Chương trình của bạn nên tính toán số người sống trong khu vực bị ảnh hưởng, đó là tổng dân số của tất cả các thành phố trong khoảng cách tới hạn của phân khúc lỗi.

Đầu vào

Đầu tiên, một dòng mô tả trận động đất, chứa tọa độ x, y của điểm bắt đầu và điểm kết thúc của sự cố, cộng với khoảng cách tới hạn. Các định dạng là A_x A_y B_x B_y D. Ví dụ:

3.0 3.0 7.0 4.0 2.5

mã hóa lỗi kéo dài từ (3.0,3.0) đến (7.0,4.0) và khoảng cách tới 2,5.

Thứ hai, một dòng trên mỗi thành phố trong khu vực, chứa tọa độ x, y của thành phố và dân số. Ví dụ:

1.0 1.0 2500
5.0 7.0 8000
3.0 4.0 7500
9.0 6.0 3000
4.0 2.0 1000

nhập mô tả hình ảnh ở đây

Đầu ra

Số người sống trong khu vực bị ảnh hưởng. Đối với ví dụ trên, chỉ có các thành phố thứ ba và thứ năm nằm trong khu vực nguy hiểm, vì vậy đầu ra sẽ là

8500

Mã ngắn nhất sẽ thắng.

Ví dụ 2

0.0 0.0 10.0 0.0 5.0
5.0 4.0 10000
5.0 -4.0 1000
5.0 6.0 100
11.0 2.0 10 
-4.0 4.0 1

tạo ra

11010

Là đầu ra phải là một số nguyên, hoặc sẽ 8500.0là ok cho ví dụ? Và chúng ta có thể có thêm một số testcase?
Ventero

Ngoài ra, loại đầu vào là gì? Như trong, nó có thể có bao nhiêu chữ số thập phân? Điều này có liên quan đến các ngôn ngữ không có dấu phẩy động.
Peter Taylor

Đầu ra cần phải là một số nguyên, không thể có người phân số. Giả sử đầu vào nhiều nhất là 2 chữ số thập phân.
Keith Randall

Là khu vực quan trọng mở rộng trong một hình bán nguyệt xung quanh các điểm cuối, hoặc nó chỉ là một hình chữ nhật?
Peter Olson

@Peter: Nó kết thúc bằng hình bán nguyệt, vì vậy toàn bộ hình dạng hình thoi.
Keith Randall

Câu trả lời:


11

Ruby, 171 152 155 153

u,v,a,b,d=gets.split.map &:to_f
a-=u;b-=v
p eval$<.map{|l|"(x=%f-u;t=(a*x+b*y=%f-v)/(a*a+b*b);d*d<(x-a*t=t<0?0:t>1?1:t)**2+(y-t*b)**2?0:%d)"%l.split}*'+'

Đây là lần gửi ruby ​​đầu tiên của tôi và golf-code đầu tiên của tôi. Thẳng tiến thực hiện nhiệm vụ. Xin vui lòng cho tôi một số gợi ý làm thế nào để cải thiện (phải có một cách ngắn hơn để đọc phao ...).


Bạn có thể tiết kiệm một vài ký tự bằng cách loại bỏ các dấu ngoặc xung quanh mapeval, và nội tuyến t. Và vì bạn đã sẵn sàng, bạn có thể sử dụng chuỗi định dạng thay vì .to_f, vì vậy khối cuối cùng có thể được rút ngắn thànhp eval$<.map{|l|"(x=%f-u;t=(x*a+b*y=%f-v)/(a**2+b**2);d*d<(x-t=t<0?0:t>1?1:t)**2+(y-t*b)**2?0:%d)"%l.split}*'+'
Ventero

@Ventero cảm ơn bạn. Nội tuyến tmột lần nữa tiết kiệm hai.
Howard

Tôi không thể làm điều này để làm việc trên ví dụ # 2 (vừa thêm), nó bị lỗi vớiundefined method > for nil:NilClass (NoMethodError)
Keith Randall

@Keith cũng nên làm việc với đầu vào của bạn.
Howard

4

Javascript (437)

Điều này có thể có thể được đánh golf đáng kể, nhưng không đủ để đánh bại giải pháp Ruby.

p=$("#i").text().split("\n");for(i=0;i<p.length;i++){p[i]=p[i].split(" ")}
z=p[0];a=z[0];b=z[1];c=z[2];d=z[3];e=z[4];o=0;f=[a,b];g=[c,d];
function q(r,s){return Math.sqrt(Math.pow(s[0]-r[0],2)+Math.pow(s[1]-r[1],2))}
for(i=1;i<p.length;i++){w=p[i];u=((w[0]-a)*(c-a)+(w[1]-b)*(d-b))/Math.pow(q(f,g,2),2);
x=[(a*1)+u*(c-a),(b*1)+u*(d-b)];l=e;m=w[2]*1;u=w[0];w=w[1];v=[u,w];
o+=q(v,x)<l&&q(x,g)+q(x,f)==q(f,g)?m:q(v,f)<l?m:q(v,g)<l?m:0}alert(o);

Bạn có thể thấy nó trong hành động ở đây .


2
Bạn có thể lưu 2 ký tự bằng cách sử dụng b-0thay vì (b*1)1 ký tự bằng cách xóa dấu chấm phẩy. Cuối cùng, bắt đầu M=Mathvà thay thế tất cả Maths bằng M, lưu 6 ký tự. Sử dụng Prototype và .valuelưu 2 ký tự ( #dấu ngoặc đơn và một).
Ry-

4

C # - 743 715

namespace System{using Linq;using m=Math;class P{public float X,Y;}class E{static void Main(){Func<string,float>p=s=>float.Parse(s);Func<P,P,double>d=(a,b)=>{return a.X*b.X+a.Y*b.Y;},c=(a,b)=>{return a.X*b.Y-a.Y*b.X;};Func<P,P,P>u=(a,b)=>{return new P{X=a.X-b.X,Y=a.Y-b.Y};};Func<P,P,P,double>g=(A,B,C)=>{return d(u(C,B),u(B,A))>0?m.Sqrt(d(u(B,C),u(B,C))):d(u(C,A),u(A,B))>0?m.Sqrt(d(u(A,C),u(A,C))):m.Abs(c(u(B,A),u(C,A))/m.Sqrt(d(u(B,A),u(B,A))));};var n=IO.File.ReadAllLines("i");var i=n[0].Split();var q=new{A=new P{X=p(i[0]),Y=p(i[1])},B=new P{X=p(i[2]),Y=p(i[3])},D=p(i[4])};Console.WriteLine((from l in n.Skip(1)let f=l.Split()let w=new P{X=p(f[0]),Y=p(f[1])}where g(q.A,q.B,w)<q.D select p(f[2])).Sum());}}}

Không chơi gôn:

namespace System
{
    using Linq;
    using m = Math;
    class Point { public float X, Y;}
    class Earthquake
    {
        static void Main()
        {
            Func<string, float> parse = s => float.Parse(s);
            Func<Point, Point, double> dotProduct = (a, b) => { return a.X * b.X + a.Y * b.Y; }, 
                                       crossProduct = (a, b) => { return a.X * b.Y - a.Y * b.X; };
            Func<Point, Point, Point> subtract = (a, b) => { return new Point { X = a.X - b.X, Y = a.Y - b.Y }; };
            Func<Point, Point, Point, double> getDistance = (A, B, C) => { 
                return dotProduct(subtract(C, B), subtract(B, A)) > 0 ? 
                        m.Sqrt(dotProduct(subtract(B, C), subtract(B, C))) : 
                        dotProduct(subtract(C, A), subtract(A, B)) > 0 ? 
                            m.Sqrt(dotProduct(subtract(A, C), subtract(A, C))) : 
                            m.Abs(crossProduct(subtract(B, A), subtract(C, A)) / m.Sqrt(dotProduct(subtract(B, A), subtract(B, A)))); 
            };
            var inputLines = IO.File.ReadAllLines("i"); 
            var quakeLine = inputLines[0].Split(); 
            var quake = new { 
                PointA = new Point { X = parse(quakeLine[0]), Y = parse(quakeLine[1]) }, 
                PointB = new Point { X = parse(quakeLine[2]), Y = parse(quakeLine[3]) }, 
                Distance = parse(quakeLine[4]) 
            };
            var affectedPopulations = (from line in inputLines.Skip(1) 
                                       let fields = line.Split() 
                                       let location = new Point { X = parse(fields[0]), Y = parse(fields[1]) } 
                                       let population = parse(fields[2])
                                       where getDistance(quake.PointA, quake.PointB, location) < quake.Distance 
                                       select population);
            Console.WriteLine(affectedPopulations.Sum());
        }
    }
}

Có gì đó không ổn với phiên bản chơi gôn, tôi gặp lỗi khi biên dịch nó ( quake.cs(1,254): error CS1525: Unexpected symbol ',', expecting 'from', 'group', 'join', 'let', 'orderby', 'select', or 'where'). Phiên bản không có tác dụng hoạt động tốt.
Keith Randall

@KeithRandall, ôi - chơi golf quá nhiều!
Rebecca Chernoff

2

c - 471 ký tự

#include <stdio.h>
#define F float
#define G getline(&v,&l,stdin)
F a[2],b[2],c[2],d[2],e[2],r,t,y,z;char*v;size_t l,n,p;
F s(F u[2],F v[2]){y=u[0]-v[0];z=u[1]-v[1];return y*y+z*z;}
j(F g[2],F h[2],F i[2]){*i=*g-*h;i[1]=g[1]-h[1];}
int i(){j(b,a,d);j(c,a,e);t=*d**e+d[1]*e[1];
return s(a,c)<=r||s(b,c)<=r||t>0&&t/s(a,b)<=1&&s(a,c)-t*t/s(a,b)<=r;}
int main(){G;sscanf(v,"%f %f %f %f %f",a,a+1,b,b+1,&r);r*=r;
while(G!=-1)sscanf(v,"%f %f %i",c,c+1,&p),n+=p*i();printf("%d\n",n);}

Nó giả sử thư viện tiêu chuẩn của bạn có getline.

Phương pháp được làm rõ một chút trong nhận xét cho phiên bản không được chỉnh sửa:

#include <stdio.h>

float a[2],b[2],c[2],d[2],e[2],r,t,y,z;
char*v;
size_t l,n,p;
float s(float u[2],float v[2]){ /* returns the square of the distance
                   between two points */
  y=u[0]-v[0];
  z=u[1]-v[1];
  return y*y+z*z;
}
j(float g[2],float h[2],float i[2]){ /* sets i=g-h */
  i[0]=g[0]-h[0];
  i[1]=g[1]-h[1];
}
int i/*sCLose*/(){
  j(b,a,d); /* d=b-a */
  j(c,a,e); /* e=c-a */
  t=d[0]*e[0]+d[1]*e[1]; /* dot product */ 
  return 
    (s(a,c)<=r) || /* near one end point */
    (s(b,c)<=r) || /* near the other */
    (  
     (t>0) && /* C lies more "towards" B than away */
     (t/s(a,b)<=1) && /* Nearest point on AB to C lies between A and B */
     (s(a,c)-t*t/s(a,b)<=r) /* length of the altitude less than R */
       ); 
}
int main(){
  getline(&v,&l,stdin);
  sscanf(v,"%f %f %f %f %f",a,a+1,b,b+1,&r);
  r*=r; /* r is now r squared, as that is the only way we use it */
  printf("(%f, %f); (%f, %f): %f\n",a[0],a[1],b[0],b[1],r);
  while (getline(&v,&l,stdin) != -1){
    sscanf(v,"%f %f %i",c,c+1,&p);
    printf("\t (%f, %f): %d\n",c[0],c[1],p);
    n+=p*i/*sClose*/();
  }
  printf("%d\n",n);
}

0

scala: 660 ký tự:

object E extends App{
type I=Int
type D=Double
def b(h:D,i:D,x:I,y:I,d:D)=(x-h)*(x-h)+(y-i)*(y-i)<=d*d
def a(p:java.awt.Polygon,x:I,y:I,h:I,i:I,d:D,r:Array[String])={
val w=r(0).toDouble
val j=r(1).toDouble
val n=r(2).toInt
if (p.contains(w,j)||b(j,w,x,y,d)||b(j,w,i,h,d))n
else 0}
val s=new java.util.Scanner(System.in)
val b=s.nextLine.split(" ")
val c=b.map(_.toDouble)
val e=c.map(_.toInt)
val(x,h,y,i,d)=(e(0),e(2),e(1),e(3),c(4))
val f=List(x,h)
val g=List(y,i)
val p=new java.awt.Polygon((f:::f.reverse).toArray,(g.map(_-e(4)):::g.reverse.map(_+e(4))).toArray,4)
var r=0
while(s.hasNext){
val row=s.nextLine
r+=a(p,x,y,h,i,d,row.split(" "))}
println(r)}

vô dụng:

object Earthquake extends App {

  def bowContains (h: Double, i: Double, x:Int, y:Int, d: Double) : Boolean = {
    (x-h)*(x-h) + (y-i)*(y-i) <= d*d
  }

  import java.awt._    

  def affected (polygon: Polygon, x:Int, y:Int, h: Int, i: Int, d: Double, row: Array[String]) : Int = {
    val w = row (0).toDouble 
    val j = row (1).toDouble 
    val population = row (2).toInt
    if (polygon.contains (w, j) || bowContains (j, w, x, y, d) || bowContains (j, w, i, h, d))
      population 
    else 0 
  }
  val sc = new java.util.Scanner (System.in)
  val line = sc.nextLine.split (" ")

  val li = line.map (_.toDouble)
  val ll = li.map (_.toInt)

  val (x, h, y, i, d) = (ll (0), ll (2), ll (1), ll (3), li(4))
  val xs = List (x, h)
  val ys = List (y, i)

  val polygon = new Polygon ((xs ::: xs.reverse).toArray, (ys.map (_ - ll(4)) ::: ys.reverse.map (_ + ll(4))).toArray, 4)
  var res = 0 
  while (sc.hasNext) {
    val row = sc.nextLine
    println ("line: " + line) 
    res += affected (polygon, x, y, h, i, d, row.split (" "))     
  } 
  println (res)
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.