Yazdığım fonksiyonlar hız testini geçemiyor

Soru şu fonksiyona bir sayı giriliyor sayının rakamlarının yer değiştirilmesi ile oluşan ve kendisinden büyük olan ilk sayıyı döndürüyor.
Örnek: 251 çıktısı 512
Yazdığım fonksiyonlardan bazen ilki daha hızlı bazen ikincisi ama ikiside testen geçemedi daha uygun algoritma nasıl olabilir

def next_bigger(n):
    def permutations(s):
        if len(s) == 0:
            return []
        elif len(s) == 1:
            return [s]
        else:
            return set(s[i] + p for i in range(len(s)) for p in permutations(s[:i] + s[i + 1:]))

    arr=[int(i) for i in permutations(str(n)) if int(i)>n]
    if arr==[]:
        return -1
    else:
        return min(arr)
1 Beğeni
def next_bigger(sayı):

    for i  in range(sayı+1,10**len(str(sayı))):
        if set(str(i))==set(str(sayı)):
            sayaç=0
            for j in str(sayı):
                if str(sayı).count(j)==str(i).count(j) :
                    sayaç+=1
            if sayaç==len(str(sayı)):
                return i
    else :
        return -1

Hangi sıra ile yer değiştirdiğinde?

Testi geçmenin gereklilikleri ne?

Öyle bir kısıtlama yok
Sürede yanlış hatırlamıyorsam 12000 ms yazıyordu

Belli bir sıra yoksa “ilk sayı” da yoktur. Yoksa bir sayının rakamlarının yeri değiştirildiğinde elde edeceğimiz, ilk sayıdan büyük olan herhangi bir sayıyı mı döndürmemiz lazım?

Hangi parametreler ile bu süre içerisinde değer döndürmesi gerekiyor?

Soruyu daha düzgün ifade etmeye çalıştım yukarda düzenleme yaptım kendisinden büyük ilk sayı yine o rakamlarla oluşturulan buda varsa tabiki yoksa 0 dönsün

Siz girdinin kendisinden büyük, en küçük sayıyı istiyorsunuz sanırım. Doğru mu?

Evet ama girdinin içindeki tüm rakamlar o sayıda olacak (tekrar edenler dahil)
Örnek:girdi 144 ise çıktı 414

Bunu bende bilmiyorum codewars sitesini bilirsiniz oradan bu soru ilk testi geçiyor onaylama aşamasındaki testte verilen sürede yapılamadı diyor.
Translate ile çeviriyorum soruları anlamak da zor oluyor bende kendince türkçe ifade edip yazıyorum.
Bazen kendim bazı örneklerde değişiklik yapıp farklı varyasyonlarını soruyorum ama bu orijinal hali tabi benim anladığım kadarı ile :slight_smile:

/*


   ***   	         *
    *                  *
    *                  *
    *	 ****	 ****  *****    ****   *   *
    *	*   *   *      *   *    *  *   *   *
    *	*   *   *      *   *    *  *   *   *
*   *	*   *   *      *   *    *  *   *****
*   *	*   *   *      *   *    *  *       *
 ***	 *** *  *      *****    *** *      *
                                           *
********************************************

*/

/*ya parçalayacam ya parçalayacam ya da parçalayacammm :)*/


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

#define rep(i, n) for(ll i = 0; i < n; i++)
#define ceza(i, n) for(ll i = n - 1; i >= 0; i--)
#define RUN_JARBAY_RUN ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define vll vector<ll>
#define deql deque<ll>
#define vi vector<int>
#define sll stack<ll>
#define pqueue priority_queue
#define pll pair<ll, ll>
#define mp make_pair
#define ff first
#define ss second
#define mete make_tuple
#define pb push_back
#define pf push_front
#define popf pop_front
#define popb pop_back

#define gcd __gcd
#define lcm(x, y) x * y / gcd(x, y)
#define get_digit(a) a - '0'
#define tos(x, y) string x; stringstream strstream; strstream << y; strstream >> x; 
#define all(a) a.begin(), a.end()
#define dbg_list(a)  cout<<"debug: "<<#a<<" "; for(ll i : a) { cout<<i<<" ";} cout<<endl;
#define dbg(a) cout<<"debug: "<<#a<<" : "<<a<<endl;
#define dbg2(a, b) cout<<"debug: "<<#a<<" : "<<a<<" || "<<#b<<" : "<<b<<endl;
#define inf 1000000009 // 10^9 + 9
#define mod 1000000007 // 10^9 + 7

// WARNING: only for int, not long long
#define clz(x) __builtin_clz(x) // the number of zeros at the beginning of the number
#define ctz(x) __builtin_ctz(x) // the number of zeros at the end of the number
#define popcount(x) __builtin_popcount(x) // the number of ones in the number
#define parity(x) __builtin_parity(x) // the parity (even or odd) of the number of ones

// for long long
#define clzll(x) __builtin_clzll(x) // the number of zeros at the beginning of the number
#define ctzll(x) __builtin_ctzll(x) // the number of zeros at the end of the number
#define popcountll(x) __builtin_popcountll(x) // the number of ones in the number
#define parityll(x) __builtin_parityll(x) // the parity (even or odd) of the number of ones

//node definition
struct node
{
  ll data;
  struct node *next;
};

typedef struct node Node;

//linked list definition
struct LinkedList
{
  Node *head;
  Node *tail;
};

typedef struct LinkedList LinkedList;

// definitions for problems
string s;

void solve()
{
  cin>>s;
  ll n = s.size();
  vi a(n);
  vll digit(10, 0);
  rep(i, n) a[i] = get_digit(s[i]), digit[a[i]]++;
  
  ll start = -1;
  ll end = -1;
  ll want = -1;
  rep(i, n)
  {
    for(int j = a[i] + 1; j < 10; j++)
      if(digit[j] > 0) start = i, want = j, j = 10;

    if(a[i] == want) end = i;
    digit[a[i]]--;
  }
  if(start < 0) cout<<0; // failed
  else
  {
    swap(a[start], a[end]);
    sort(a.begin() + start + 1, a.end());
    rep(i, n) cout<<a[i];
  }
  cout<<endl;
}


int main()
{
  RUN_JARBAY_RUN
  
  #ifdef JARBAY_DEBUG
    clock_t start = clock();
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
  #endif
  
  ll t = 1;
  //cin>>t;
  rep(i, t)
    solve();
    
  #ifdef JARBAY_DEBUG
    double EXECUTION_TIME = (double(clock()) - double(start)) / double(CLOCKS_PER_SEC);
    cout<<"*******************************************"<<endl;
    cout<<"EXECUTION TIME: "<<EXECUTION_TIME<<endl;
  #endif
		
}

Ben de böyle bir implementation yaptım.

Sen şu problemin linkini atsana mutlaka input format output format vardır. Orada input limitlerini de belirtirler mutlaka, en azından codeforces.com da öyle.

Yakın zamanda benzer bir soru çözmüştüm, incelemek istersen şöyle bırakıyorum.

1 Beğeni


sorunun orjinali burada

kodu girdikten sonraki durumlarda

Öncelikle zahmet edip açıklama yaptığın için teşekkürler.Ama amatör olduğum için teknik detaylardan pek anlamıyorum.Konuyu inceleyen diğer arkadaşlar faydalanacaktır.Anladığım kadarıyla kod biraz bilgisayarı yoracak karmaşıklıkta daha basite indirgenmeli

1 Beğeni

Ben teşekkür ederim.

Ben de amatörüm.

Aynen öyle hocam.

Sizin durumunuzu şimdi anlıyorum. Beni python’a parçalattın ya, helal olsun hocam :smile:

Python ile bir implementation yazmaya çalıştım. sample testin 5. sini geçemedim.

gerisini siz düzenleseniz çok makbule geçer hocam, ben düzenleyemedim de, düzenleyebilirsem editlerim.
cpp ile yazdığım kodu 5.input ile denedim, doğru çıktıyı veriyor.

def next_bigger(n):
    n = str(n)
    a = []
    digit = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    for i in n:
        digit[int(i)] += 1
        a.append(int(i))
    start = -1; end = -1; want = -1
    for i in range(len(a)):
        for j in range(a[i] + 1, 10):
            if(digit[j] > 0):
                start = i
                want = j
                break
        if(a[i] == want):
          end = i
        digit[a[i]] -= 1
        
    if(start == -1): return 0
    else:
        a[start] , a[end] = a[end] , a[start]
        a[start + 1::].sort()
        res = 0
        for i in range(len(a)):
          res += a[i] * (10**(len(a) - 1 - i))
        return res

İyi geceler hocam, kolay gelsin

EDIT: Bugı anladım, ama nasıl çözeceğimi bilmiyorum. Ben belirli bir segmenti sıralamak istiyorum, ama sıralamıyor. Bunu bir düşüneceğim.

EDIT2: Hele şükür şimdi çözdüm. Şu çok işime yaradı.

def next_bigger(n):
    n = str(n)
    a = []
    digit = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    for i in n:
        digit[int(i)] += 1
        a.append(int(i))
    start = -1; end = -1; want = -1
    for i in range(len(a)):
        for j in range(a[i] + 1, 10):
            if(digit[j] > 0):
                start = i
                want = j
                break
        if(a[i] == want):
          end = i
        digit[a[i]] -= 1
        
    if(start == -1): return 0
    else:
        a[start] , a[end] = a[end] , a[start]
        # print(start, a)
        b = a[start + 1::]
        b.sort()
        a[start + 1::] = b
        res = 0
        for i in range(len(a)):
          res += a[i] * (10**(len(a) - 1 - i))
        return res
1 Beğeni

Tebrikler senin algoritma testi geçti
Ben şunu çok beğendim

def next_bigger(n):
    if str(n) == ''.join(sorted(str(n))[::-1]):
        return -1
    a = n
    while True:
        a += 1
        if sorted(str(a)) == sorted(str(n)):
            return a
1 Beğeni

buda başka bir çözüm

def next_bigger(n):
    s = list(str(n))
    for i in range(len(s)-2,-1,-1):
        if s[i] < s[i+1]:
            t = s[i:]
            m = min(filter(lambda x: x>t[0], t))
            t.remove(m)
            t.sort()
            s[i:] = [m] + t
            return int("".join(s))
    return -1

Ikinci dereceli, hatta lineer zamanli bir cozumun mumkun olmasi lazim. Yururken dusunucem ama koda aktaracak vaktim olmaz herhalde.

Soyle bir sey: Son iki basamaga bak, yer degistirdiklerinde sayi buyuyorsa bitti. Buyumuyorsa ucuncu basmaga bak, son 3 rakam arasindan bir buyugunu koy, kalanlari kucukten buyuge yerlestir. Buyumuyorsa dorduncu basamaga bak, son 4 rakam arasindan bir buyugunu koy, kalanlari kucukten buyuge…

Çözüm olarak işaretlediğim sizin dediğinize benzer bir yol izliyor sanırsam

Kendi yazdiginiz kodun nasil calistigini bilmiyor musunuz?