শহরগুলি: দর্শনীয় স্থান


18

আমি একটি অসীম দ্বি-মাত্রিক শহরের অবস্থান (0, 0) এ আছি , যা প্রতিটি জাল পয়েন্টকে কেন্দ্র করে ব্লকগুলিতে পুরোপুরি বিভক্ত, যার কয়েকটিতে বিল্ডিং রয়েছে। একটি নির্দিষ্ট পয়েন্টে (x, y) একটি বিল্ডিং এর সীমানা সহ (x-.5, y-.5) এবং (x + .5, y + .5) এর বিপরীত কোণগুলির সাথে পুরো বর্গক্ষেত্রটি নিয়ে যায় । (0, 0) থেকে ভবনের কোনও বিন্দুতে কিছু রেখাংশ রয়েছে যা অন্য কোনও বিল্ডিকে ছেদ করে না যদি কোনও বিল্ডিং দৃশ্যমান হয় ।

উদাহরণস্বরূপ, আমি (দ্য @) *নিম্নলিখিত শহরে 6 টি বিল্ডিং ( ) দেখতে পাচ্ছি :

  *
 *
*
*@
x**
 *  y

আমি (-1, -1)x এ একটি দিয়ে চিহ্নিত বিল্ডিংটি দেখতে পাচ্ছি না কারণ এটি সংলগ্ন দুটি দ্বারা বাধা রয়েছে; অথবা এক একটি দিয়ে চিহ্নিত করা এ (3, -2) কারণ এটি প্রান্ত দ্বারা বাধিত এর (1, -1) ভবন।y

ইনপুট

একটি মাল্টলাইন স্ট্রিং, বা রেখার তালিকা optionচ্ছিকভাবে আয়তক্ষেত্রে ফাঁকা স্থান সহ প্যাড করা। এটিতে কেবল এটিই থাকবে:

  • একক @(আমার অবস্থান)
  • শূন্যস্থানের
  • *, যা বিল্ডিং প্রতিনিধিত্ব করে।

সর্বদা কমপক্ষে একটি বিল্ডিং থাকবে এবং তাই কমপক্ষে একটি দৃশ্যমান বিল্ডিং থাকবে।

আউটপুট

দৃশ্যমান ভবনের সংখ্যা।

পরীক্ষার মামলা

*@
1

* *******
 @     * 
7

*****
**@**
*****
4

   *
  **
@ **
2

*      *
 *    * 
@
4

@
 *
  ***
1

শিরোনামের জন্য @ জিওবিটসকে ধন্যবাদ ।



টেস্ট কেস 3 সম্পর্কে, এটি 8 * দ্বারা বেষ্টিত তবে ফলাফল 4 But তবে corn কোণগুলি অন্য ভবনগুলি দ্বারা অবরুদ্ধ বলে মনে হচ্ছে না। কোণগুলি অন্তর্ভুক্ত না করার কোনও নিয়ম আছে?
লুক্সটর্মস

1
@ লুক্সটর্মস কল্পনা করুন যে প্রতিটি তারা মাইনক্রাফ্টের মতো প্রকৃতপক্ষে কিউবস। আপনি যদি এর মাঝে দাঁড়িয়ে থাকেন তবে আপনি কেবল 4 টি ব্লক দেখতে সক্ষম হবেন
ব্লু

অনুগ্রহপূর্বক পুরষ্কার প্রদানের আগে আমার গল্ফযুক্ত সমাধান (খুব শীঘ্রই) প্রবেশ করার আগে কি আপনি অপেক্ষা করার মতো দয়া করবেন? :)
লিফ উইলার্টস

উত্তর:


4

ইউনিটি + সি #, 589 বাইট

কোড গল্ফটি করার জন্য এটি সম্ভবত সবচেয়ে খারাপ ভাষা (পড়ুন: জাভা থেকেও খারাপ), তবে ityক্য এই চ্যালেঞ্জের জন্য অনেক সহায়ক বৈশিষ্ট্য নিয়ে আসে।

সম্পাদনা: কয়েকটি জায়গা ফাঁকা হয়েছে, তালিকার দৈর্ঘ্য রয়েছে, পাল্টা নয়

Golfed:

using UnityEngine;using System.Collections;public class c:MonoBehaviour{public int h(string[]i){ArrayList k=new ArrayList();for(int y=0;y<i.Length;y++){char[]l=i[y].ToCharArray();int x=0;foreach(char c in l){if(c=='*'){GameObject b=GameObject.CreatePrimitive(PrimitiveType.Cube);b.transform.position=new Vector3(x,y);}if(c=='@')transform.position=new Vector3(x,y);x++;}}for(int n=0;n<3600;n++){RaycastHit h;Physics.Raycast(transform.position,Quaternion.Euler(0,0,n/10)*Vector3.up,out h);if(h.collider!=null){GameObject o=h.collider.gameObject;if(!k.Contains(o))k.Add(o);}}return k.Count;}}

Ungolfed:

using UnityEngine;
using System.Collections;

public class citiessightlines : MonoBehaviour {

    public ArrayList todelete;   // Anything concerning this array just has to do with cleanup of 
                                 //objects for testing, and doesn't contribute to the byte count.
    void Start()
    {
        todelete = new ArrayList();
    }
    public int calcSight(string[]input)
    {
        todelete = new ArrayList();
        int total = 0;
        ArrayList check = new ArrayList();
        for (int y=0;y < input.Length; y++)
        {
            char[] line = input[y].ToCharArray();
            for (int x = 0; x < line.Length; x++)
            {
                char c = line[x];
                if (c == '*')
                {
                    GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                    cube.transform.position = new Vector3(x, y);
                    todelete.Add(cube);
                }
                if (c == '@')
                {
                    transform.position = new Vector3(x, y);
                }
            }
        }
        for (int angle=0; angle < 3600; angle++)
        {
            RaycastHit hit;
            Physics.Raycast(transform.position, Quaternion.Euler(0, 0, angle/10) * Vector3.up, out hit);
            if (hit.collider!=null)
            {
                GameObject hitObject = hit.collider.gameObject;
                if (!check.Contains(hitObject)&&hitObject!=this)
                {
                    total += 1;
                    check.Add(hitObject);
                }
           }
        }
        return total;
    }
}

আমি 3600 রাইকেস্ট ব্যবহার করেছি কারণ এটি 5 তম টেস্ট কে নিম্নের সাথে ব্যর্থ করে। এটি আরও বৃহত্তর / আরও সুনির্দিষ্ট পরীক্ষার ক্ষেত্রেও ব্যর্থ হতে পারে।

দুর্ভাগ্যবশত, উভয় WebGL এবং ডেস্কটপ তৈরী করে বিরতি বলে মনে হচ্ছে, তাই আমি সঙ্গে পরীক্ষা সোর্স কোড GitHub উপর


read: worse than Javaএটি জাভা সমাধানের চেয়ে 383 বাইট কম !
ব্যবহারকারী 8397947

@ ডোরুকায়হান আমার অর্থ যে বেশিরভাগ বিল্ট-ইনরা জাভা থেকে বেশি ভার্বোস
নীল

আমি সি # জানি না কিন্তু আপনি প্রতিস্থাপন করতে পারেনি total+=1সঙ্গে total++? আমি মনে করি কিছু অক্ষর সংরক্ষণের অন্য উপায় হ'ল বিল্ডিংয়ের কিউব তৈরি করা এবং এটি একটি বিবৃতিতে এর অবস্থান নির্ধারণ করা। আপনি cubeভেরিয়েবলটি কোথাও পুনরায় ব্যবহার করবেন বলে মনে হয় না ।
হিজড়া

@ ফ্রোজেন আমি আসলে আমার গল্ফড কোডে এটি করছি না
ব্লু

কেবল কোডটির দিকে তাকিয়ে দেখেছেন যে আপনি সেখানে গণনা পরিবর্তন করেছেন। আমি সবসময় ধরেই নিয়েছি যে গল্ফ করা সংস্করণটি কেবলমাত্র একটি সাদা জায়গা-স্ট্রিপড সংস্করণ, তবে এটি এখানে সম্ভবত স্পষ্ট নয়। দ্বিতীয় অংশটি সম্পর্কে: আমি মনে করি আপনি করেন। এটা GameObject b=GameObject.CreatePrimitive(PrimitiveType.Cube);b.transform.position=new Vector3(x,y);। এটি সি # তে সম্ভব কিনা তা আমি জানি না তবে জাভাতে এর GameObject.CreatePrimitive(PrimitiveType.Cube).transform.position=new Vector3(x,y);পরিবর্তে কেউ লিখতে পারেন ।
হিমায়িত

3

জাভা 8 লাম্বদা, 1506 1002 972 942 টি অক্ষর

আমি এই চ্যালেঞ্জটি পরাজিত করতে চেয়েছিলাম, কারণ এটি অত্যন্ত আকর্ষণীয়। ফলাফল (খুব গল্ফ নয়) এখানে দেখা যায়:

import java.util.*;f->{Set<double[]>B=new HashSet(),r,n;double a,M,m,P=Math.PI*2,z=.5;int x=0,y,v=0,i,j,c[],p,q,l=g.length;for(;x<l;x++)for(y=0;y<g[x].length;y++)if(g[x][y]>63)for(;;){c=new int[]{-1};M=2e31-1;for(i=0;i<l;i++)for(j=0;j<g[i].length;j++)if(g[i][j]==42)if((m=(p=x-i)*p+(q=y-j)*q)<M){M=m;c=new int[]{i,j};}if(c[0]<0)break;g[c[0]][c[1]]=0;double[]A={(a=Math.atan2((c[1]-=y)-z,(c[0]-=x)-z))<0?a+P:a,(a=Math.atan2(c[1]+z,c[0]-z))<0?a+P:a,(a=Math.atan2(c[1]+z,c[0]+z))<0?a+P:a,(a=Math.atan2(c[1]-z,c[0]+z))<0?a+P:a};r=new HashSet();M=-P;m=P;for(double d:A){M=d>M?d:M;m=d<m?d:m;}r.add(new double[]{m,M});for(double[]t:B){n=new HashSet();for(double[]h:r)for(double[]u:t[0]<h[0]?t[1]<h[0]?new double[][]{h}:t[1]<h[1]?new double[][]{{t[1],h[1]}}:new double[0][]:t[0]>h[1]?new double[][]{h}:t[1]>h[1]?new double[][]{{h[0],t[0]}}:new double[][]{{h[0],t[0]},{t[1],h[1]}})if(u[0]<u[1])n.add(u);r=n;}B.addAll(r);if(!r.isEmpty())v++;}return v;}

অবশ্যই এটি অসম্পূর্ণ সংস্করণেও বিদ্যমান:

import java.util.*;

public class AngleCheck {

    static int getViewableBuildingsC(char[][] grid) {

        Set<double[]> blocked = new HashSet(), ranges, newRanges;

        double angle, max, min, PI2 = Math.PI * 2, half = 0.5;

        int x = 0, y, viewable = 0, i, j, building[], dX, dY, length = grid.length;

        for (; x < length; x++) {
            for (y = 0; y < grid[x].length; y++) {
                if (grid[x][y] > 63) {
                    for (;;) {
                        building = new int[]{-1};
                        max = 2e31-1;
                        for (i = 0; i < length; i++) {
                            for (j = 0; j < grid[i].length; j++) {
                                if (grid[i][j] == 42) {
                                    if ((min = (dX = x - i) * dX + (dY = y - j) * dY) < max) {
                                        max = min;
                                        building = new int[]{i, j};
                                    }
                                }
                            }   
                        }

                        if (building[0] < 0)
                            break;

                        grid[building[0]][building[1]] = 0;
                        double[] angles = {
                                        (angle = Math.atan2((building[1] -= y) - half, (building[0] -= x) - half)) < 0 ? angle + PI2 : angle,
                                        (angle = Math.atan2(building[1] + half, building[0] - half)) < 0 ? angle + PI2 : angle,
                                        (angle = Math.atan2(building[1] + half, building[0] + half)) < 0 ? angle + PI2 : angle,
                                        (angle = Math.atan2(building[1] - half, building[0] + half)) < 0 ? angle + PI2 : angle};

                        ranges = new HashSet();

                        max = -PI2;
                        min = PI2;
                        for (double d : angles) {
                            max = d > max ? d : max;
                            min = d < min ? d : min;
                        }

                        ranges.add(new double[]{min, max});

                        for (double[] reference : blocked) {
                            newRanges = new HashSet();
                            for (double[] currentRange : ranges) {
                                for (double[] subRange : reference[0] < currentRange[0] ?
                                            reference[1] < currentRange[0] ?
                                                // whole range after referencerange
                                                new double[][]{currentRange}
                                            :
                                                reference[1] < currentRange[1] ?
                                                    // lower bound inside referencerange, but upper bound outside
                                                    new double[][]{{reference[1], currentRange[1]}}
                                                :
                                                    // whole range inside referencerange -> nothing free
                                                    new double[0][]
                                        :
                                            // greater or equal lower bound
                                            reference[0] > currentRange[1] ?
                                                // whole range before referencerange
                                                new double[][]{currentRange}
                                            :
                                                // ranges overlap
                                                reference[1] > currentRange[1] ?
                                                    // range starts before and ends in reference range
                                                    new double[][]{{currentRange[0], reference[0]}}
                                                :
                                                    // referencerange is in the range -> two free parts, one before, one after this
                                                    new double[][]{{currentRange[0], reference[0]}, {reference[1], currentRange[1]}}) {
                                    if (subRange[0] < subRange[1])
                                        newRanges.add(subRange);
                                }
                            }
                            ranges = newRanges;
                        }

                        blocked.addAll(ranges);
                        if (!ranges.isEmpty()) {
                            viewable++;
                        }
                    }
                }
            }
        }
        return viewable;
    }
}

সুতরাং এটি দেখতে খুব কঠিন দেখাচ্ছে তবে এটি মনে করার চেয়ে সহজ উপায়। আমার প্রথম ধারণাটি ছিল আমার পজিশন থেকে বিল্ডিংয়ের কোনও লাইন কোনও ছেদ ছাড়াই তৈরি করা যায় কিনা তা পরীক্ষা করার জন্য কিছু ছেদটি অ্যালগরিদম ব্যবহার করা to এটি করার জন্য আমি কোহেন-সুদারল্যান্ড অ্যালগরিদম ব্যবহার এবং বিল্ডিংয়ের চারটি কোণে লাইন আঁকানোর সিদ্ধান্ত নিয়েছি। এটি প্রথম পরীক্ষাগুলির জন্য বেশ ভাল কাজ করেছে, তবে শেষটি ব্যর্থ হয়েছিল। আমি শীঘ্রই খুঁজে পেয়েছি, এটি এমন একটি ঘটনা যেখানে আপনি কোণগুলি দেখতে পাচ্ছেন না তবে একটি প্রান্তের একটি অংশ। তাই আমি ভেবেছিলাম এমন কিছু ধরণের রে কাস্টিংয়ের কথা যেমন @ ব্লু এটি করেছে। আমি কিছুটা অগ্রগতি না পাওয়ায় আমি সেই চ্যালেঞ্জটিকে সরিয়ে দিয়েছি। তারপরে আমি নীলির উত্তর দেখেছি এবং নিম্নলিখিত সাধারণ ধারণাটি আমার মনে এসেছিল: প্রতিটি বিল্ডিং এমন একটি কোণকে বাধা দেয় যেখানে অন্য কোনও কিছুই দেখা যায় না। আমাকে কেবল কী দেখা যায় এবং অন্যান্য ইমারতগুলির দ্বারা ইতিমধ্যে কী লুকানো আছে তার খোঁজ রাখা দরকার। এটাই!

অ্যালগরিদম নিম্নলিখিত হিসাবে কাজ করে: এটি ব্যক্তির সবচেয়ে ছোট দূরত্ব সহ বিল্ডিংটি নির্ধারণ করে। তারপরে আমরা ব্যক্তি থেকে বিল্ডিংয়ের কোণে টানা চারটি লাইন কল্পনা করি। এর মধ্যে দুটির একটি চূড়ান্ত মান রয়েছে: সর্বনিম্ন এবং সর্বোচ্চ কোণ যাতে বিল্ডিংটি দেখা যায়। আমরা এগুলিকে একটি ব্যাপ্তি হিসাবে গ্রহণ করি এবং তাদের সাথে অন্যান্য বিল্ডিংয়ের সাথে তুলনা করি যা আমরা জানি যে তারা দেখা যায় (শুরুতে কিছুই নেই)। ব্যাপ্তিগুলি একে অপরকে ওভারল্যাপ করতে পারে, একে অপরকে অন্তর্ভুক্ত করতে পারে বা একেবারে স্পর্শ করে না। আমি রেঞ্জগুলি তুলনা করি এবং বিল্ডিংয়ের কয়েকটি নতুন রেঞ্জ পাই যা দেখতে পাওয়া যায় না এমন দালানগুলির দ্বারা গোপন নয়। দর্শনীয় স্থানগুলির সাথে এটির তুলনা করার পরে যদি কিছু অবশিষ্ট থাকে তবে বিল্ডিংটিও দৃশ্যমান। আমরা পরের দীর্ঘ দূরত্বের সাথে পরবর্তী বিল্ডিংয়ের সাথে তুলনা করতে এবং শুরু করার জন্য রেঞ্জগুলির তালিকায় অবশিষ্ট কোণ রেঞ্জ যুক্ত করি।

কখনও কখনও সীমাগুলি এমনভাবে ওভারল্যাপ হতে পারে যে আমি 0 ডিগ্রি ব্যাপ্তির সাথে শেষ করি। এই রেঞ্জগুলি ভুলভাবে এমন একটি বিল্ডিংয়ের জন্য ফিল্টার করা হবে যা এমনকি দেখা যায় না।

আমি আশা করি কেউ এই ব্যাখ্যাটি বুঝতে পেরেছে :)

আমি জানি এই কোডটি খুব বেশি গল্ফ হয় না, আমি এটিকে তাত্ক্ষণিকভাবে করব।

এটি ছিল সত্যিই চ্যালেঞ্জিং কাজ। আপনি ভেবেছিলেন যে এমন একটি সমাধান খুঁজে পেয়েছে যা কাজ করে তবে পরিবর্তে আপনি এখনও অনেক দূরে। আমি মনে করি এই সমাধানটি বেশ ভাল কাজ করে। এটি খুব দ্রুত নয় তবে অন্তত এটি কাজ করে;) সেই ধাঁধার জন্য ধন্যবাদ!


হালনাগাদ

আমি পুরো জিনিসটি একটি একক কার্যক্রমে ডুবিয়ে দেওয়ার জন্য সময় পেয়েছি, যা এভাবে ল্যাম্বডায় রূপান্তরিত হতে পারে। সমস্ত ফাংশন কেবল একবার কল করা হয়েছিল এবং সুতরাং এটি একটি পদ্ধতিতে রাখা যেতে পারে। আমি তালিকাগুলি থেকে সেটগুলিতে স্যুইচ করেছি কারণ এটি কিছু অতিরিক্ত অক্ষর সংরক্ষণ করে। ঘোষণা একসাথে রাখা হয়েছে। তুলনা একসাথে করা হয়েছে এবং অক্ষরগুলি সেখানে ascii মান দ্বারা প্রতিস্থাপিত হয়েছে। পরিসীমা তুলনা অনেক অঞ্চল হিসাবে প্রকাশ করা যেতে পারে। ডাবলের মতো দীর্ঘ অভিব্যক্তিগুলি রোধ করতে এখানে এবং সেখানে কিছু কৌশল NNEGATIVE_INFINITY সম্পন্ন হয়েছে। যেখানে সম্ভব ইনলাইন অ্যাসিগমেন্টগুলি সম্পন্ন হয়। আরও কিছুটা বাঁচাতে আমি ডিগ্রিগুলিতে কোণগুলি তুলনা করে রেডিয়ানের সাথে তুলনা করে স্যুইচ করেছি। পুরো পরিবর্তনটি 500 টিরও বেশি অক্ষর সাশ্রয় করেছে, আমি আশা করি এটি 1000 এর অধীনেই পেয়ে যাব;)

আমি যেখানে সম্ভব জেনেরিকগুলি সরিয়েছি এবং একটি উপাদান অ্যারে তৈরি করে রিটার্নের তুলনা কমিয়ে দিয়েছি এবং পরিবর্তে এর মানটি পরীক্ষা করেছি। আমি ডাবলকেও প্রতিস্থাপন করেছি N এখন এটি শেষ পর্যন্ত 1000 টিরও বেশি দীর্ঘ!

আমি কিছু অক্ষর সংরক্ষণ করতে ব্যক্তির অবস্থান এবং বিল্ডিং পুনরুদ্ধারের সন্ধানের জন্য লুপগুলি একত্রিত করেছি। দুর্ভাগ্যক্রমে এর জন্য আমাদের লুপটির বাইরে ফেরত সরানো এবং এখনও একটি বিরতি ব্যবহার করা প্রয়োজন তবে এবার কোনও লেবেল ছাড়াই। আমি মিশে গিয়ে তৈরি maxএবং distanceSquaredএবং minএবং newDistanceSquaredতারা একই সময়ে প্রয়োজন হয় না। আমি পরিবর্তন Integer.MAX_VALUEকরতে 2e31-1। এছাড়াও আমি একটি ধ্রুবক তৈরি করেছি half = 0.5যা বিল্ডিংয়ের কোণগুলি গণনা করতে ব্যবহৃত হয়। এটি গল্ফযুক্ত সংস্করণে খাটো। সামগ্রিকভাবে আমরা আরও 30 টি অক্ষর সংরক্ষণ করেছি!


চমৎকার গল্ফ! আমি সমস্ত অন্তর্নির্মিত রাই কাস্টিংয়ের সাহায্যে একটি সহজ রুট নিয়েছি, তবে আমি সাহায্য করেছি তা জেনে আনন্দিত! (বিটিডব্লিউ আমি সম্ভবত সেটেও পরিবর্তন করব)
ব্লু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.