try bloğundaki her şey zaten yakalandığında yakala


19

Bu sanırım sözdizimi ile Java ve C # ile sınırlıdır.

Bu programlama bulmacasında, Exceptionyakalanabilecek ancak catch bloğunun sonunda tekrar atılan s'ler üreteceksiniz .

try
{
    while(true)
        try
        {
            // you are only allowed to modify code between this try { } brackets
        }
        catch(Exception ex2) {  }
}
catch(Exception ex1)
{
    // your goal is to reach this catch block by modifying the code ...
    // in the inner try block above
    // You win if you reach this part and execute on of the following code lines
    Console.WriteLine("You won!"); // for C#
    // Or
    System.out.println("You won!"); // for Java
}

Kodu bu snippet'in önüne ve arkasına serbestçe koyabilirsiniz.

Dış catchbloğa ulaşmak için en kısa kod kazanır.


1
Bence Python da rekabet edebilir.
user12205

1
Kodumu pasajımın önüne ve arkasına özgürce koyabilirsiniz.
user21634

2
Çok kötü kapalı. Bir çözüm buldum . @Algorithmshark, Michael ve Jan Dvorak için: Bu genel bir programlama sorusu DEĞİLDİR. Bu benzer bir programlama puzzle olduğunu zürafa değil bir zürafa ne zaman? . Bunu tekrar açmak için aday gösteriyorum.
user12205

1
Uhhhhhh, Whaaat ???
TheDoctor

1
@algorithmshark Eklemelerin uzunluklarının toplamı ile giderdim
user12205

Yanıtlar:


24

C #, 46 (kazan plakası dahil 88)

using System;class P{static void Main(){
        try
        {
            while(true)
                try
                {
                    System.Threading.Thread.CurrentThread.Abort();
                }
                catch(Exception ex2) {  }
        }
        catch(Exception ex1)
        {
            // your goal is to reach this catch block by modifying the code ...
            // in the inner try block above
            // You win if you reach this part and execute on of the following code lines
            Console.WriteLine("You won!"); // for C#
        }
}}

Abort()Yöntem, bir yükseltir ThreadAbortException (sürece otomatik olarak her tutma bloğunun sonunda rethrown özel bir durum olan, Thread.ResetAbort()olarak adlandırılır).


20

C # 24 Karakter

denemeden önce iç try bloğunu sonlandırır, try bloğunun dışında bir istisnama neden olmamı sağlar.

}finally{int a=1/0;}try{

1
Adamım bu dahi! Neden böyle düşünmedim? (Btw, bir istisna atmak yerine bir istisna oluşturarak kısaltabilir misiniz? Örneğin int a=1/0;?)
user12205

int a=Orada ihtiyacın var mı? Bazı diller sadece ifadeyi yazmanıza izin veriyor1/0
gnibbler

Bu tam bir çalışma örneği değil, değil mi? 24 karakter sayılmaz ...
Matt

13

Java, 76 veya 31

Yalnızca koda yapılan eklemeleri sayarak yeni satırları yok sayar. 76 eklediğim her şeyi sayarsanız , 31 ilk satırı ve son satırı hariç tutarsanız, yani yalnızca sayma int a=1/0;try{}catch(Error e){}.

class P{public static void main(String[]A){
try
{
    while(true)
        try
        {
            int a=1/0;try{
        }
        catch(Exception ex2) {  }
}
catch(Exception ex1)
{
    // your goal is to reach this catch block by modifying the code ...
    // in the inner try block above
    // You win if you reach this part and execute on of the following code lines
    //Console.WriteLine("You won!"); // for C#
    // Or
    System.out.println("You won!"); // for Java
}
}catch(Error e){}
}}

Üzgünüz, nasıl saydığınıza dikkat etmedim. Diğer sayma yöntemini eklemek için cevabımı güncelleyeceğim. Ben sadece try bloğundaki karakterleri saymak daha iyidir, aksi takdirde temelde C # vs Java boilerplate karşılaştırmak olacaktır. Ancak, birisi try bloğunun dışında önemli kodlarla bir cevap gönderirse (kuralların izin verdiği gibi) bu karmaşıklaşabilir.
BenM

@BenM Endişelenme ve neden böyle saydığınızı anlıyorum. Sadece OP hangi şekilde sayılacağını belirtmedi, bu yüzden ikisini de dahil edeceğimi düşündüm.
user12205

Çok akıllıca bir çözüm.
Nicolas Barbulesco

@NicolasBarbulesco Dürüst olmak gerekirse, Ryan'ın cevabının benden daha akıllı olduğunu düşünüyorum. Sonuçta, catchpasajdan sonra bir blok ekledim , yapmadı.
user12205

3

Uyarı : Bu programlar klon bombalarıdır (bir çeşit daha az tehlikeli ama yine de tehlikeli bir çatal bomba şekli); bu nedenle, bunları korumalı alan veya kaynak sınırları olmadan bir üretim sisteminde çalıştırmayın . Klon bombaları bir döngüde iplikler oluşturur (bir döngüde süreçler oluşturan çatal bombalarının aksine), böylece söz konusu işlemi öldürerek (onları çok zor olabilecek çatal bombalarından çok daha az tehlikeli hale getirerek) durdurabilirsiniz. temizle); ancak siz bunu yapmayı başarana kadar (veya program kendi kendine kazanıp çıkana kadar) işlemcinizin çoğunu bağlarlar. İşletim sisteminizden, bu programların kullanmasına izin verilen bellek ve CPU süresine sınır koymasını istemek, bunları test etmek için güvenli bir ortam oluşturmalıdır.

Java (OpenJDK 8) , 65 60 bayt (paketleyicide küçük bir değişiklikle)

Thread x=Thread.currentThread();new Thread(x::stop).start();

Çevrimiçi deneyin!

catch (Exception …)Sorunun her iki örneğinin de değiştirilmesini gerektirir catch (Throwable …). Bu teorik olarak daha az değil daha güvenli olmalıdır , ancak bu çözümün mümkün olmasını sağlar.

Lambda yerine yöntem referansı kullanarak bu cevabın ilk versiyonu üzerine 5 bayt kazandım.

Java 4, 104 bayt (denenmemiş, orijinal sarıcı ile çalışmalıdır)

final Thread x=Thread.currentThread();new Thread(){public void run(){x.stop(new Exception());}}.start();

Çevrimiçi deneyin! (bağlantı bir Java 8 uygulamasına gider, bu nedenle çalışmaz)

Java'nın modern sürümlerinden kaldırılan özellikleri kullanarak, bulmacanın gerektiren bir sürümünü bile çözmek mümkündür Exception. Muhtemelen, en azından. (Java 4 şimdiye kadar çok eskidir ve hangi özellikleri içerdiğini ve içermediğini hatırlayamıyorum. Görüldüğü gibi Java'da çok daha az özellik vardı ve bu yüzden daha ayrıntılıydı; lambdas, bu yüzden bir iç sınıf yaratmak zorunda kaldım.)

açıklamalar

Bu sorunun çözümlerinin çoğu C # (bir kod enjeksiyon biçimi olarak dengesiz köşeli parantez kullanarak hile yapan bir Java çözümü ve Java'da olmayan bir Perl çözümü ile birlikte). Bu yüzden bu bulmacanın Java'da da "düzgün" olarak nasıl çözülebileceğini göstermeye değer olacağını düşündüm.

Her iki program da etkili bir şekilde aynıdır (bu nedenle, ilk programın işe yaraması gerçeği, yanlışlıkla Java-4 olmayan bir özellik kullanmadıkça ikinci programın da işe yarayacağına dair yüksek güven veriyor; Thread#stopJava 5'te kullanımdan kaldırıldı).

Java'nın Thread#stopyöntemi, sahnenin arkasında, atılabilir bir parçanın söz konusu konuya atılmasına neden olarak çalışır. Bu amaca yönelik atılabilir ThreadDeath(bir Error, özellikle insanlar genellikle istisnaları batırmaya çalıştığı ve Java tasarımcıları bunu olmasını istemediği için), ancak herhangi bir şey atmanıza izin verir (veya alışkın; API'den sonra bir noktada) Java'nın tasarımcıları bunun inanılmaz derecede kötü bir fikir olduğunu fark etti ve argümanları doğrudan alan yöntemin sürümünü kaldırdı). Tabii ki, fırlatan sürüm bile, ThreadDeathbirkaç garanti verebileceğiniz oldukça riskli bir işlemdir (örneğin, bu bulmacayı çözmenize izin verir, "mümkün olmaması gereken" bir şey), kullanın, ancak Java 8'den itibaren hala çalışıyor.

Bu program yeni bir iş parçacığı oluşturarak ve ana iş parçasına zorla bir istisna atmasını isteyerek çalışır. Eğer şanslıysak, bunu iç catchbloğun dışında olduğumuz bir zamanda yapacağız ( catchprogram bitene kadar dış bloktan kaçamayız , çünkü etrafında bir döngü var). Döngüyü zaten uygun bir şekilde eklediğimiz için, bir tanesi sonunda doğru zamanlamaya ulaşacağını umarak, iş parçacıkları oluşturmaya devam etmemize izin vermek için bu döngüyü kullanmak bayt tasarrufu sağlıyor. Bu normalde birkaç saniye içinde gerçekleşir.

(TIO notu: TIO'nun mevcut sürümü, muhtemelen tüm oluşturulan iş parçacıkları nedeniyle, bu programı yürütüldüğünde erken öldürmeye eğilimlidir. TIO üzerinde çalışabilir, ancak güvenilir bir şekilde çalışmaz, bu nedenle genellikle "Sen kazandın!" çıktısını al.)


1

C #

    try
    {
        int i = 0, j = 1, k;

        int flag = 0;
        lbl:
        if (flag == 1)
        {
            k = j / i;
        }

        while (true)
            try
            {
                k = j / i;

            }
            catch (Exception e)
            {
                flag = 1;
                goto lbl;
                //Console.WriteLine("loose");

            }
    }
    catch (Exception e)
    {
        Console.WriteLine("Won");

    }

1
Programlama Bulmacaları ve Kod Golf hoş geldiniz! Bu soru bir kod golf zorluğu olduğundan, lütfen kodunuzu mümkün olduğunca kısa tutmaya çalışın ve cevabınızın üst kısmına karakter sayısını ekleyin. Teşekkürler!
ProgramFOX

1

Perl 5 , 37 veya 36 bayt

eval {
    while (1) {
        eval {

 

use overload'""',sub{die};die bless[]

 

        };
        $@ eq "" or 0;
    }
};
$@ eq "" or print "You won!\n";

Çevrimiçi deneyin!

Bu sorunun, orada da ilginç bir bulmaca yapacak kadar Perl'e dönüştüğü ortaya çıkıyor. Perl tryeşdeğeri çağrılır (biraz kafa karıştırıcı) evalve @_gerçekleşmesi durumunda bir istisnayı, aksi halde null dizesini ayarlayarak bir istisna belirtir . Bu nedenle, null dizeyle catchkarşılaştırılarak bir blok uygulanır @_.

Bu çözüm bir nesne oluşturarak çalışır (sınıfı bir bütün olarak programdır; sınıflar gibi rasgele Perl dosyalarını kullanabilirsiniz, bir çeşit Java'nın tersi gibi (dosyalar gibi rasgele sınıfları kullanabilirsiniz). Bu bless[]kısım ( blessnormalde sadece yapıcıların derinliklerinde görünür, ilk etapta nesneleri nesneye dönüştüren ilkel olarak, ancak bunu gerçekten istiyorsanız doğrudan kullanabilirsiniz; []nesnenin bellek ayırıcısıdır - bir liste yapıcısı, bu case - ve sınıf verilmez, bu nedenle şu anda yürütülen sınıf olduğu varsayılır). Bu arada, "sınıfımıza" (yani ana dosyaya) özel bir dizeden karşılaştırma yöntemini veriyoruz use overloadve bu yöntemin bir istisna atmasını sağlıyoruz (böylece döngüden koparak bulmacayı çözüyoruz); aslında koyabilirizuse overloadve her ne kadar geleneksel olarak diğer yöntem tanımlarına girip dosyanın üst kısmına yaklaşsa da, yerine verdiğimiz boşluğa koyabiliriz ve hala çalışır. (Dosyanın sonuna koyarsak, noktalı virgülün ardından atlanabilir ve 36 baytlık bir çözüme yol açabiliriz, ancak bu ilk başta bir noktalı virgül içeren programa bağlı olduğundan tartışmalı bir şekilde hile yapıyor. Aslında stringize işlemine aşırı yüklenmek ve Perl'in bununla bir dizgiyi otomatik olarak oluşturmasına izin vermek daha kısadır, dize karşılaştırmasını doğrudan aşırı yüklemeden daha fazla olacaktır (çünkü bazı operatörlerin aşırı yüklenmesi sizi diğer operatörleri aşırı yüklemeye zorlar).

Şimdi tek yapmamız gereken nesneyi kullanarak atmak die. evalBiz karşılaştırmak istediğinizde sonlandığı sonra $@boş dizeye karşılaştırma başka istisna atar ve biz dış kaçış, (bir istisna olmadığını görmek için) eval.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.